并發(fā)網(wǎng)絡(luò)服務(wù)器 + 網(wǎng)絡(luò)編程

并發(fā)網(wǎng)絡(luò)服務(wù)器:

  • 基本概念解釋

多進(jìn)程并發(fā)服務(wù)器

togglesp.c

void sigchld_handler(int sig) {  
  while (waitpid(-1, 0, WNOHANG) > 0); 
  return; 
}

 int main(int argc, char **argv) {
    int listen_sock, conn_sock, port;
    socklen_t clientlen=sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    if (argc != 2) {   …   }
    port = atoi(argv[1]);
    signal(SIGCHLD, sigchld_handler);
    listen_sock = open_listen_sock(port);
    while (1) {
        conn_sock = accept(listen_sock, (SA *) &clientaddr, &clientlen);
        if (fork() == 0) { 
           close(listen_sock); 
           toggle(conn_sock);      /* Child process services client */
           close(conn_sock);      
           exit(0);       
        }
       close(conn_sock);
    }
}

特點(diǎn):父子共享打開(kāi)文件表劳坑,但不共享用戶地址空間若厚。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):每個(gè)進(jìn)程都有獨(dú)立的地址空間裙士,進(jìn)程間不會(huì)相互影響,有較好的可靠性和安全性
缺點(diǎn):進(jìn)程間共享狀態(tài)信息變得麻煩,IPC機(jī)制開(kāi)銷(xiāo)很高心剥,進(jìn)程間數(shù)據(jù)共享低效

基于多線程并發(fā)服務(wù)器

togglest.c:

int main(int argc, char **argv) { 

    int listen_sock, *conn_sock_p, port;
    socklen_t clientlen=sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    pthread_t tid;  
    if (argc != 2) {。瘩缆。关拒。    }

    port = atoi(argv[1]);
    listen_sock = open_listen_sock(port);
    while (1) {
        conn_sock_p = malloc(sizeof(int));
        *conn_sock_p = accept(listen_sock, (SA *) &clientaddr, &clientlen);
        pthread_create(&tid, NULL, serve_client, conn_sock_p); 
    }
}

void * serve_client (void *vargp) {  
    int conn_sock = *((int *)vargp);
    pthread_detach(pthread_self()); 
    free(vargp);
    toggle(conn_sock);
    close(conn_sock);

    return NULL;
}

預(yù)線程化并發(fā)服務(wù)器

  1. 基本思想
    預(yù)先創(chuàng)建一批工作者線程,每次建立一個(gè)連接庸娱,工作者線程就領(lǐng)取一個(gè)任務(wù)着绊,負(fù)責(zé)與一個(gè)客戶端通信以消除服務(wù)器運(yùn)行過(guò)程中創(chuàng)建、撤銷(xiāo)線程的開(kāi)銷(xiāo).


    image.png

任務(wù)池定義(task_pool.c涌韩、task_pool.h)

生產(chǎn)者/消費(fèi)者模型

# inpos畔柔、outpos分別是緩沖區(qū)寫(xiě)入、讀出指針
# mutex:為互斥信號(hào)量
# avail臣樱、ready是同步信號(hào)量

typedef struct {
    int *socks;         /* Buffer array */         
    int cnt;            /* Maximum number of cell */
    int inpos;          /* buf[inpos] is first available cell */
    int outpos;         /* buf[outpos] is fist item */
    sem_t mutex;      /* Protects accesses to socks */
    sem_t avail;       /* Counts available cells */
    sem_t ready;      /* Counts ready items */
} task_pool_t;

緩沖區(qū)初始化

void task_pool_init(task_pool_t *tp, int n)
{
    tp->socks = Calloc(n, sizeof(int)); 
    tp->cnt = n;                     /* socks holds max of n items */
    tp->inpos= tp->outpos = 0;           /* Empty socks iff inpos== outpos */
    sem_init(&tp->mutex, 0, 1);       /* Binary semaphore for locking */
    sem_init(&tp->avail, 0, cnt);       /* Initially, socks has cnt empty cell */
    sem_init(&tp->ready, 0, 0);        /* Initially, socks has zero data items */
}

讀寫(xiě)緩沖區(qū)

void task_insert (task_pool_t *tp, int item){  

    sem_wait(&tp->avail);           /* Wait for available cell */
    sem_wait(&tp->mutex);          /* Lock the shared variable tail pointer */
    tp->socks[tp->inpos] = item;        /* Insert the item */
    tp-> inpos =(tp-> inpos +1)%(tp->cnt); /* adjuset tail point */
    sem_post(&tp->mutex);          /* Unlock the buffer */
    sem_post(&tp->ready);          /* Announce available item */
}

int task_remove(task_pool_t *tp){靶擦。腮考。。}

預(yù)線程化服務(wù)器代碼(togglest_pre.c)

int main(int argc, char **argv) { 
    int i, listen_sock, conn_sock, port;
    socklen_t clientlen=sizeof(struct sockaddr_in);
    struct sockaddr_in clientaddr;
    pthread_t tid;  

    if (argc != 2) { 玄捕。踩蔚。。    }
    port = atoi(argv[1]);
    task_pool_init(&tp, SBUFSIZE);
    listen_sock = open_listen_sock(port);

    for (i = 0; i < NTHREADS; i++)  /* Create worker threads */
        pthread_create(&tid, NULL, serve_client, NULL);
        while (1) { 
          conn_sock = accept(listen_sock, (SA *) &clientaddr, &clientlen);
          task_insert(&tp, conn_sock);    /* Insert conn_sock in task pool */
    }
}

void * serve_client(void *vargp) {  

    pthread_detach(pthread_self()); 
    while (1) { 
       int conn_sock = task_remove(&tp); 
       toggle(conn_sock);
       close(conn_sock);
    }
}

網(wǎng)絡(luò)編程:

套接字枚粘、


套接字編程模型

結(jié)構(gòu):網(wǎng)卡馅闽、TCP協(xié)議、套接字(Socket)
套接字:含有進(jìn)程接收信息的完整地址(Socket地址:IP地址馍迄、端口號(hào))

  • Internet連接客戶端與服務(wù)器的網(wǎng)卡,
  • TCP/IP協(xié)議軟件連接Socket與網(wǎng)卡,
  • 套接字接口連接進(jìn)程與Socket,
image.png

TCP連接整合了以上兩個(gè)工具,tcp連接是連接通訊雙方套接字的一條通信線路.一條TCP連接實(shí)際上就是一個(gè)文件描述符,可用read/write或send/recv進(jìn)行數(shù)據(jù)收發(fā).

  • TCP連接實(shí)例
    服務(wù)器端口號(hào):規(guī)定為80
    客戶端端口號(hào):隨機(jī)分配福也,12345


    image.png

字節(jié)序、

  • 網(wǎng)絡(luò)序(網(wǎng)絡(luò)序):高位在低地址字節(jié)


    大端模式
  • 主機(jī)序(小端模式):低位在低地址字節(jié)


    小端模式
  • 主機(jī)序與網(wǎng)絡(luò)序的轉(zhuǎn)換
    unsigned long int htonl(unsigned long int hostlong);
    unsigned short int htons(unsigned short int hostshort);
    返回:網(wǎng)絡(luò)序的值攀圈。
    unsigned long int ntohl(unsigned long int netlong);
    unsigned short int ntohs(unsiged short int netshort);
    返回:主機(jī)序的值暴凑。

  • IP地址
    由32位整數(shù)網(wǎng)絡(luò)序0x8002c2f2轉(zhuǎn)換成點(diǎn)分十進(jìn)制128.2.193.242
    128=0x80,2=0x02赘来,193=0xc2现喳,242=0xf2
    轉(zhuǎn)換函數(shù):
    int inet_aton(const char *cp, struct in_addr *inp);
    char *inet_ntoa(struct in_addr in);
    a: 字符串 n:32位整數(shù)

網(wǎng)絡(luò)通信API函數(shù):

編程框架

(一)客戶端
(1)創(chuàng)建套接字
int socket(int domain, int type , int protocol);
示例:client_sock = socket(AF_INET , SOCK_STREAM, 0);
(2) connect 函數(shù)
int connect (int client_sock , struct sockaddr *serv_addr , int addrlen);
(3)包裝函數(shù)open_client_sock

(二)服務(wù)器端
(1)創(chuàng)建
int socket(int domain, int type , int protocol);
(2)綁定
int bind(int serv_sock, struct sockaddr *my_addr , int addrlen);
(3)監(jiān)聽(tīng)
int listen(int serv_sock, int backlog);
(4)接受連接請(qǐng)求
int accept(int listen_sock, struct sockaddr *addr , int *addrlen);
包裝函數(shù):open_listen_sock

服務(wù)器與客戶端連接
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市犬辰,隨后出現(xiàn)的幾起案子嗦篱,更是在濱河造成了極大的恐慌,老刑警劉巖幌缝,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灸促,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡狮腿,警方通過(guò)查閱死者的電腦和手機(jī)腿宰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缘厢,“玉大人,你說(shuō)我怎么就攤上這事甩挫√颍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵伊者,是天一觀的道長(zhǎng)英遭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)亦渗,這世上最難降的妖魔是什么挖诸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮法精,結(jié)果婚禮上多律,老公的妹妹穿的比我還像新娘痴突。我一直安慰自己,他們只是感情好狼荞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布辽装。 她就那樣靜靜地躺著,像睡著了一般相味。 火紅的嫁衣襯著肌膚如雪拾积。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天丰涉,我揣著相機(jī)與錄音拓巧,去河邊找鬼。 笑死一死,一個(gè)胖子當(dāng)著我的面吹牛肛度,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摘符,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贤斜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了逛裤?” 一聲冷哼從身側(cè)響起瘩绒,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎带族,沒(méi)想到半個(gè)月后锁荔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蝙砌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年阳堕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片择克。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恬总,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肚邢,到底是詐尸還是另有隱情壹堰,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布骡湖,位于F島的核電站贱纠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏响蕴。R本人自食惡果不足惜谆焊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浦夷。 院中可真熱鬧辖试,春花似錦辜王、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至肾档,卻和暖如春摹恰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怒见。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工俗慈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遣耍。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓闺阱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親舵变。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酣溃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)編程 一.楔子 你現(xiàn)在已經(jīng)學(xué)會(huì)了寫(xiě)python代碼赊豌,假如你寫(xiě)了兩個(gè)python文件a.py和b.py,分別去運(yùn)...
    go以恒閱讀 2,024評(píng)論 0 6
  • 大綱 一.Socket簡(jiǎn)介 二.BSD Socket編程準(zhǔn)備 1.地址 2.端口 3.網(wǎng)絡(luò)字節(jié)序 4.半相關(guān)與全相...
    VD2012閱讀 2,362評(píng)論 0 5
  • socket通信原理 socket又被叫做套接字,它就像連接到兩端的插座孔一樣,通過(guò)建立管道绵咱,將兩個(gè)不同的進(jìn)程之間...
    jiodg45閱讀 1,144評(píng)論 0 1
  • 網(wǎng)絡(luò)模型 物理層 物理層表示的是比特流傳輸碘饼,通常包括串口/COM口、并行/LPT口悲伶、USB艾恼、網(wǎng)線接口、電話線接口麸锉;...
    秋風(fēng)弄影閱讀 720評(píng)論 0 2
  • 第一章 引言和網(wǎng)絡(luò)編程基礎(chǔ)知識(shí) 1.1 分別簡(jiǎn)述OSI參考模型和TCP/IP模型钠绍,并闡述他們之間的對(duì)應(yīng)關(guān)系 1.2...
    V0W閱讀 5,335評(píng)論 0 9