您当前的位置: 首页 > 

phymat.nico

暂无认证

  • 0浏览

    0关注

    1967博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

listen()函数中backlog参数分析

phymat.nico 发布时间:2017-12-17 23:48:04 ,浏览量:0

背景知识

Unix网络编程描述如下:

总结

0. accept()函数不参与三次握手,而只负责从已建立连接队列中取出一个连接和sockfd进行绑定; 1. backlog参数决定了未完成队列和已完成队列中连接数目之和的最大值(从内核角度看,是否这个和就是等于sock->recv_queue ?); 2. accept()函数调用,会从已连接队列中取出一个“连接”(可以是一个描述连接的数据结构,listensocket->sock->recv_queue[sk_buff] ? ),未完成队列和已完成队列中连接数目      之和将减少1;即accept将监听套接字对应的sock的接收队列中的已建立连接的sk_buff取下(从该sk_buff中可以获得对端主机的发送过来的tcp/ip数据包) 3. 监听套接字的已完成队列中的元素个数大于0,那么该套接字是可读的。 4. 当程序调用accept的时候(设置阻塞参数),那么判定该套接字是否可读,不可读则进入睡眠,直至已完成队列中的元素个数大于0(监听套接字可读)而唤起监听进程。

实例分析1

将服务器端的listen函数backlog设置为2,用20个客户端与服务器建立连接,查看连接的建立情况。

服务器代码:

[cpp] view plain copy
  1. #include   
  2. #include  
  3. #include       /* basic system data types */  
  4. #include      /* basic socket definitions */  
  5. #include      /* sockaddr_in{} and other Internet defns */  
  6. #include       /* inet(3) functions */  
  7. #include       /* epoll function */  
  8. #include  
  9. #include  
  10. #include  
  11. #include  
  12. #include  
  13.   
  14.   
  15. int main(int argc,char*argv[])  
  16. {  
  17.     int listenfd,connfd;  
  18.     struct sockaddr_in cliaddr,servaddr;  
  19.     int queuelen=5;  
  20.   
  21.     if(argc!=2){  
  22.         puts("usage# ./aworker listenqueuelen");  
  23.         exit(0);  
  24.     }     
  25.     queuelen=atoi(argv[1]);  
  26.   
  27.     listenfd = socket(AF_INET,SOCK_STREAM,0);  
  28.   
  29.     bzero(&servaddr,sizeof(servaddr));  
  30.     servaddr.sin_family = AF_INET;  
  31.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  32.     servaddr.sin_port = htons(2989);  
  33.       
  34.     bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));  
  35.       
  36.     listen(listenfd,queuelen);  
  37.     sleep(60); //将这个注释,会出现另一种情况哟~~    
  38.     while(1)  
  39.     {  
  40.         connfd = accept(listenfd,NULL,0);  
  41.         if(connfd == -1)  
  42.         {  
  43.             perror("accept error");  
  44.             continue;  
  45.         }  
  46.         puts("new connection...");  
  47.     }  
  48.     return 0;  
  49. }  
client代码
[cpp] view plain copy
  1. #include "client.h"  
  2.   
  3. //void cli_hander(int sockfd,)  
  4.   
  5. int main()  
  6. {  
  7.     int sockfd;  
  8.     int rc;   
  9.     int cpid;  
  10.     struct sockaddr_in servaddr;  
  11.       
  12.     bzero(&servaddr,sizeof(servaddr));  
  13.     servaddr.sin_family = AF_INET;  
  14.     inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);  
  15.     servaddr.sin_port = htons(2989);  
  16.       
  17.     for(int i=0;i
关注
打赏
1659628745
查看更多评论
立即登录/注册

微信扫码登录

0.0487s