C語言socket send()資料緩衝問題

來源:互聯網
上載者:User

標籤:禁用   inux   調用   cpp   緩衝   listen   str   bytes   set   

send()函數預設情況下會使用Nagle演算法。Nagle演算法通過將未確認的資料存入緩衝區直到積攢到一定數量一起發送的方法。來降低主機發送零碎小資料包的數目。所以假設send()函數發送資料過快的話,該演算法會將一些資料打包後統一發出去。假設不了接這樣的情況,接收端採會遇到看似非常奇怪的問題,比方成功recv()的次數與成功send()的次數不相等。在這中情況下,接收端能夠通過recv()的傳回值是否為0來推斷髮送端是否發送完成。

通過setsockopt()的TCP_NODELAY選項來禁用Nagle演算法。但經實驗這樣的方法似乎不總是有效,只是對於同樣數量的send(),設定了TCP_NODELAY選項後recv()成功的次數要比設定之前多出幾倍。這是不是說明設定了TCP_NODELAY後,系統會進最大的努力不去緩衝。可是假設send的實在太快的話,還是會緩衝的。

因此。假設你不希望send()的資料被本機快取到一定數量之後再發送,而是send()多少次就發送多少次。穩妥的方式還是每次send之後調用一下usleep()函數,給系統一個反應的時間。

以下的範例示範了send()調用的快慢對資料是否打包的影響,凝視掉server裡的usleep(1000),會導致資料打包發送。

TCP_NODELAY是唯一使用IPPROTO_TCP層的選項,宏TCP_NODELAY的標頭檔是linux/tcp.h或者netinet/tcp.h。

由於不知到send()資料緩衝的問題,我調試一天的程式。我的五一勞動節啊!!

server.c

#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/wait.h>#include<netinet/in.h>#include<netdb.h>#include<arpa/inet.h>#include<netinet/tcp.h>//#include<linux/tcp.h>int main(){int socksv, sockcl;struct sockaddr_in server_addr;struct sockaddr_in client_addr;int sin_size;if((socksv = socket(AF_INET, SOCK_STREAM, 0)) == -1){printf("sever socket fail\n");return -1;}memset(&server_addr, 0, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(6001);server_addr.sin_addr.s_addr = INADDR_ANY;int r = 1;setsockopt(socksv, SOL_SOCKET, SO_REUSEADDR, &r, sizeof(int));int t = 1;if(-1 == setsockopt(socksv, IPPROTO_TCP, TCP_NODELAY, &t, sizeof(int))){printf("setsockopt fail\n");return -1;}if(bind(socksv, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){printf("server bind fail\n");return -1;}if(listen(socksv, 5) == -1){printf("server listen fail\n");return -1;}while(1){sin_size = sizeof(struct sockaddr_in);if((sockcl = accept(socksv, (struct sockaddr *)&client_addr, &sin_size)) == -1){printf("server accept fail\n");continue;}int times = 1024;int allbytes = 0;int i;for(i = 0; i < times; i++){char buf[] = "#this is a message from ptypeServer";int sendbytes;if((sendbytes = send(sockcl, buf, strlen(buf), 0)) == -1){printf("server send fail\n");}usleep(1000);allbytes += sendbytes;}printf("have send %d packages to client, allbytes=%d\n", times, allbytes);close(sockcl);}}


client.c

#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/wait.h>#include<netinet/in.h>#include<netdb.h>#include<arpa/inet.h>int main(){int socksv;char buf[1024 * 1024];if((socksv = socket(AF_INET, SOCK_STREAM, 0)) == -1){printf("socket fail\n");return -1;}struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(6001);server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");if(connect(socksv, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){printf("connect fail\n");return -1;}int times = 0;int allbytes = 0;int numbytes = 1;while(numbytes != 0){times++;if((numbytes = recv(socksv, buf, sizeof(buf), 0)) == -1){printf("recv fail\n");return -1;}//buf[numbytes] = ‘\0‘;//printf("numbytes=%d buf=[%s]\n", numbytes, buf);allbytes += numbytes;}printf("server is closed, have recv %d packages from server, ""allbytes=%d\n", times - 1, allbytes);}

參閱:http://baike.baidu.com/link?url=-QgA0U7iv5tno-qnorYKDMNazOeOdcGk-pKIVFcOy-n6vhoITKdzlCg1VZYjqJ1DnOlpaaA54E7HrqQX6Bc_e_



C語言socket send()資料緩衝問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.