Linux網(wǎng)絡(luò)編程——tcp永乌、udp迭代服務(wù)器

一、迭代與并發(fā)服務(wù)器概述
服務(wù)器設(shè)計(jì)技術(shù)有很多具伍,按使用的協(xié)議來(lái)分有 TCP 服務(wù)器和 UDP 服務(wù)器翅雏,按處理方式來(lái)分有迭代服務(wù)器(循環(huán)服務(wù)器)和并發(fā)服務(wù)器。

在網(wǎng)絡(luò)程序里面人芽,一般來(lái)說(shuō)都是許多客戶對(duì)應(yīng)一個(gè)服務(wù)器(多對(duì)一)望几,為了處理客戶的請(qǐng)求,對(duì)服務(wù)端的程序就提出了特殊的要求萤厅。
目前最常用的服務(wù)器模型有:
迭代服務(wù)器:服務(wù)器在同一時(shí)刻只能響應(yīng)一個(gè)客戶端的請(qǐng)求

并發(fā)服務(wù)器:服務(wù)器在同一時(shí)刻可以響應(yīng)多個(gè)客戶端的請(qǐng)求

二橄抹、UDP 迭代服務(wù)器
UDP 循環(huán)服務(wù)器每次從套接字上讀取一個(gè)客戶端的請(qǐng)求 -> 處理 -> 然后將結(jié)果返回給客戶機(jī)。
因?yàn)?UDP 是非面向連接的惕味,沒(méi)有一個(gè)客戶端可以老是占住服務(wù)端楼誓。只要處理過(guò)程不是死循環(huán),或者耗時(shí)不是很長(zhǎng)名挥,服務(wù)器對(duì)于每一個(gè)客戶機(jī)的請(qǐng)求在某種程度上來(lái)說(shuō)是能夠滿足疟羹。
udp迭代服務(wù)器框架:

//1.創(chuàng)建套接字  
int sockfd = socket(...);  
  
//2.綁定套接字  
bind(...);  
  
while(1)  
{  
    //3.接收客戶端的請(qǐng)求  
    recvfrom(...);  
      
    //4.處理客戶端的請(qǐng)求  
    process(...);  
      
    //5.反饋處理結(jié)果  
    sendto(...);  
}  

udp迭代服務(wù)器參考代碼:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
  
int main(int argc, char *argv[])  
{  
    unsigned short port = 8080; //本地端口  
  
    //1.創(chuàng)建udp套接字  
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);   
    if(sockfd < 0)  
    {  
        perror("socket");  
        exit(-1);  
    }  
      
    // 配置本地網(wǎng)絡(luò)信息  
    struct sockaddr_in my_addr;  
    bzero(&my_addr, sizeof(my_addr));   // 清空  
    my_addr.sin_family = AF_INET;       // IPv4  
    my_addr.sin_port   = htons(port);   // 端口  
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip  
      
    printf("Binding server to port %d\n", port);  
      
    // 2.綁定套接字  
    int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));  
    if(err_log != 0)  
    {  
        perror("bind");  
        close(sockfd);        
        exit(-1);  
    }  
      
    printf("receive data...\n");  
    while(1)  
    {  
        int recv_len;  
        char recv_buf[512] = {0};  
        struct sockaddr_in client_addr;  
        char cli_ip[INET_ADDRSTRLEN] = "";//INET_ADDRSTRLEN=16  
        socklen_t cliaddr_len = sizeof(client_addr);  
          
        //3.接收客戶端的請(qǐng)求  
        recv_len = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&client_addr, &cliaddr_len);  
          
        //4.處理客戶端的請(qǐng)求,這里只是把接收過(guò)來(lái)的數(shù)據(jù)打印  
        inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);  
        printf("\nip:%s ,port:%d\n",cli_ip, ntohs(client_addr.sin_port)); // 客戶端的ip  
        printf("data(%d):%s\n",recv_len,recv_buf);  // 客戶端的數(shù)據(jù)  
          
        //5.反饋處理結(jié)果禀倔,這里把接收直接到客戶端的數(shù)據(jù)回復(fù)過(guò)去  
        sendto(sockfd, recv_buf, recv_len, 0, (struct sockaddr*)&client_addr, cliaddr_len);  
    }  
      
    close(sockfd);  
      
    return 0;  
}  

運(yùn)行結(jié)果:


三榄融、tcp迭代服務(wù)器
TCP 迭代服務(wù)器接受一個(gè)客戶端的連接,然后處理救湖,完成了這個(gè)客戶的所有請(qǐng)求后剃袍,斷開連接。TCP 迭代服務(wù)器一次只能處理一個(gè)客戶端的請(qǐng)求捎谨,只有在這個(gè)客戶的所有請(qǐng)求滿足后民效,服務(wù)器才可以繼續(xù)后面的請(qǐng)求憔维。如果有一個(gè)客戶端占住服務(wù)器不放時(shí),其它的客戶機(jī)都不能工作了畏邢,因此业扒,TCP 服務(wù)器一般很少用迭代服務(wù)器模型的。

tcp迭代服務(wù)器框架:

//1.創(chuàng)建tcp套接字  
int sockfd = socket(...);  
  
//2.綁定套接字  
bind(...);  
  
//3.監(jiān)聽(tīng)套接字  
listen(...);  
  
while(1)  
{  
    //4.提取已連接套接字  
    int connfd = accept(...);  
      
    //5.處理客戶端的請(qǐng)求  
    process(...);  
      
    //6.關(guān)閉已連接套接字  
    close(connfd);  
}  
  
//7.關(guān)閉監(jiān)聽(tīng)套接字  
close(sockfd);  

tcp迭代服務(wù)器參考代碼:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>                         
#include <unistd.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
              
int main(int argc, char *argv[])  
{  
    unsigned short port = 8080;     // 本地端口   
  
    //1.創(chuàng)建tcp套接字  
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);     
    if(sockfd < 0)  
    {  
        perror("socket");  
        exit(-1);  
    }  
      
    //配置本地網(wǎng)絡(luò)信息  
    struct sockaddr_in my_addr;  
    bzero(&my_addr, sizeof(my_addr));     // 清空     
    my_addr.sin_family = AF_INET;         // IPv4  
    my_addr.sin_port   = htons(port);     // 端口  
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip  
      
    //2.綁定  
    int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));  
    if( err_log != 0)  
    {  
        perror("binding");  
        close(sockfd);        
        exit(-1);  
    }  
      
    //3.監(jiān)聽(tīng)舒萎,套接字變被動(dòng)  
    err_log = listen(sockfd, 10);   
    if(err_log != 0)  
    {  
        perror("listen");  
        close(sockfd);        
        exit(-1);  
    }     
      
    printf("listen client @port=%d...\n",port);  
  
    while(1)  
    {     
      
        struct sockaddr_in client_addr;          
        char cli_ip[INET_ADDRSTRLEN] = "";       
        socklen_t cliaddr_len = sizeof(client_addr);      
          
        //4.取出客戶端已完成的連接  
        int connfd;  
        connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);         
        if(connfd < 0)  
        {  
            perror("accept");  
            continue;  
        }  
  
        //5.打印客戶端的ip和端口  
        inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);  
        printf("----------------------------------------------\n");  
        printf("client ip=%s,port=%d\n", cli_ip,ntohs(client_addr.sin_port));  
          
        // 接收數(shù)據(jù)  
        char recv_buf[512] = {0};  
        int len =  recv(connfd, recv_buf, sizeof(recv_buf), 0);  
          
        // 處理數(shù)據(jù)程储,這里只是打印接收到的內(nèi)容  
        printf("\nrecv data:\n");  
        printf("%s\n",recv_buf);  
          
        // 反饋結(jié)果  
        send(connfd, recv_buf, len, 0);  
          
        //6.關(guān)閉已連接套接字  
        close(connfd);       
        printf("client closed!\n");  
    }  
      
    //7.關(guān)閉監(jiān)聽(tīng)套接字  
    close(sockfd);           
      
    return 0;  
}  

運(yùn)行結(jié)果:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臂寝,隨后出現(xiàn)的幾起案子章鲤,更是在濱河造成了極大的恐慌,老刑警劉巖咆贬,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件败徊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掏缎,警方通過(guò)查閱死者的電腦和手機(jī)皱蹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)眷蜈,“玉大人沪哺,你說(shuō)我怎么就攤上這事∽萌澹” “怎么了辜妓?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)忌怎。 經(jīng)常有香客問(wèn)我嫌拣,道長(zhǎng),這世上最難降的妖魔是什么呆躲? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮捶索,結(jié)果婚禮上插掂,老公的妹妹穿的比我還像新娘。我一直安慰自己腥例,他們只是感情好辅甥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著燎竖,像睡著了一般璃弄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上构回,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天夏块,我揣著相機(jī)與錄音疏咐,去河邊找鬼。 笑死脐供,一個(gè)胖子當(dāng)著我的面吹牛浑塞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播政己,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼酌壕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了歇由?” 一聲冷哼從身側(cè)響起卵牍,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沦泌,沒(méi)想到半個(gè)月后糊昙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赦肃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年溅蛉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片他宛。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡船侧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厅各,到底是詐尸還是另有隱情镜撩,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布队塘,位于F島的核電站袁梗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏憔古。R本人自食惡果不足惜遮怜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸿市。 院中可真熱鬧锯梁,春花似錦、人聲如沸焰情。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)内舟。三九已至合敦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間验游,已是汗流浹背充岛。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工保檐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人裸准。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓展东,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親炒俱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盐肃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

  • 參考:http://www.2cto.com/net/201611/569006.html TCP HTTP UD...
    F麥子閱讀 2,940評(píng)論 0 14
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理峦阁,服務(wù)發(fā)現(xiàn)谦铃,斷路器,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • 個(gè)人認(rèn)為榔昔,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記驹闰,這雖然只是...
    貳零壹柒_fc10閱讀 5,051評(píng)論 0 8
  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的撒会,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,037評(píng)論 6 174
  • 今天敷面膜嘹朗,突發(fā)奇想用眉筆在鼻子旁邊畫了一個(gè)胡子,很搞笑诵肛。興高采烈照了一張照片屹培,想分享給他,卻發(fā)現(xiàn)我們?cè)缇筒宦?lián)系了...
    遠(yuǎn)山長(zhǎng)慕寒鴉聲渡閱讀 211評(píng)論 0 0