listen()函數中backlog參數分析
阿新 • • 發佈:2017-11-09
accep nis nbsp str .... basic and 分析 col
實例分析1
將服務器端的listen函數backlog設置為2,用20個客戶端與服務器建立連接,查看連接的建立情況。
服務器代碼:
#include <stdio.h> #include<unistd.h> #include<sys/types.h> /* basic system data types */ #include<sys/socket.h> /* basic socket definitions */ #include<netinet/in.h> /* sockaddr_in{} and other Internet defns*/ #include<arpa/inet.h> /* inet(3) functions */ #include<sys/epoll.h> /* epoll function */ #include<fcntl.h> #include<stdlib.h> #include<errno.h> #include<stdio.h> #include<string.h> int main(int argc,char*argv[]) { int listenfd,connfd;struct sockaddr_in cliaddr,servaddr; int queuelen=5; if(argc!=2){ puts("usage# ./aworker listenqueuelen"); exit(0); } queuelen=atoi(argv[1]); listenfd = socket(AF_INET,SOCK_STREAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family= AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(2989); bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); listen(listenfd,queuelen); sleep(60); //將這個註釋,會出現另一種情況喲~~ while(1) { connfd = accept(listenfd,NULL,0); if(connfd == -1) { perror("accept error"); continue; } puts("new connection..."); } return 0; }
client代碼
#include "client.h" //void cli_hander(int sockfd,) int main() { int sockfd; int rc; int cpid; struct sockaddr_in servaddr; bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr); servaddr.sin_port = htons(2989); for(int i=0;i<20;i++) { cpid = fork(); if(cpid == 0) { sockfd = socket(AF_INET,SOCK_STREAM,0); rc = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); if(rc == -1) { perror("connect error"); exit(0); } printf("pid#%d connected...\n",getpid()); sleep(3); close(sockfd); exit(0); } } while(1) { cpid = wait(NULL); if(cpid==-1){ perror("end of wait"); break; } printf("pid#%d exit...\n",cpid); } return 0; }
實驗結果
服務器端顯示:
root@cloud2:~/slp/NetWrokProgram/server# ./aworker 2 new connection... new connection... new connection... new connection... new connection...
客戶端顯示:
root@cloud2:~/slp/NetWrokProgram/client# ./a.out pid#16697 connected... pid#16699 connected... pid#16698 connected... pid#16697 exit... pid#16699 exit... pid#16698 exit... pid#16700 connected... pid#16701 connected... pid#16700 exit... pid#16701 exit... connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out connect error: Connection timed out pid#16702 exit... pid#16703 exit... pid#16704 exit... pid#16705 exit... pid#16706 exit... pid#16707 exit... pid#16708 exit... pid#16709 exit... pid#16710 exit... pid#16711 exit... pid#16712 exit... pid#16713 exit... pid#16714 exit... pid#16715 exit... pid#16716 exit... end of wait: No child processes
結果分析:
同時建立連接的客戶端進程共有20個,可是只有5個完成了連接的建立,其他15個沒有成功。有趣的是,建立的5個鏈接中有3個是馬上建立的,2個是過了一段時間後後來才建立的。
實例分析2
將server端的代碼中的sleep(60)註釋,即服務端listen即開始進入while循環中的accept阻塞:
... listen(listenfd,queuelen); sleep(60); //將這個註釋,會出現另一種情況喲~~ while(1) { connfd = accept(listenfd,NULL,0); ....
同樣的運行服務端結果如下:
root@cloud2:~/slp/NetWrokProgram/server# ./aworker 2 new connection... new connection... new connection... new connection... new connection... new connection... new connection... new connection... new connection... new connection... new connection... new connection...
客戶端
root@cloud2:~/slp/NetWrokProgram/client# ./a.out pid#16736 connected... pid#16737 connected... pid#16738 connected... pid#16739 connected... pid#16740 connected... pid#16741 connected... pid#16742 connected... pid#16743 connected... pid#16744 connected... pid#16745 connected... pid#16746 connected... pid#16747 connected... pid#16748 connected... pid#16749 connected... pid#16750 connected... pid#16751 connected... pid#16752 connected... pid#16753 connected... pid#16755 connected... pid#16754 connected... pid#16736 exit... pid#16737 exit... pid#16738 exit... pid#16739 exit... pid#16740 exit... pid#16741 exit... pid#16742 exit... pid#16743 exit... pid#16744 exit... pid#16745 exit... pid#16746 exit... pid#16747 exit... pid#16748 exit... pid#16749 exit... pid#16750 exit... pid#16751 exit... pid#16752 exit... pid#16753 exit... pid#16755 exit... pid#16754 exit... end of wait: No child processes結果分析: 由於每個連接在建立之後,已完成隊列中的連接馬上就被accept給讀取了,所以已完成和未完成隊列中的連接數之和根本不可能超過backlog限定的個數。
轉自:http://blog.csdn.net/ordeder/article/details/21551567
listen()函數中backlog參數分析