博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
日记(16)-20140928
阅读量:4595 次
发布时间:2019-06-09

本文共 3818 字,大约阅读时间需要 12 分钟。

昨天看了电影《亲爱的》,很真实。

---------------------------------------华丽分割线----------------------------------------------

好了,说说今天。

简单谈一下我对listen函数,及其背后机制的理解。  

1,内核为每个监听套接字维护2个队列:        未完成连接队列, 已完成连接队列。

2,建立三次握手后,sockfd从未完成连接队列加入已完成连接队列。

3,accept()函数不参与三次握手,而只负责从已建立连接队列中取出一个连接和本地连接 进行绑定;

4,backlog参数决定了未完成队列和已完成队列中连接数目之和的最大值

5,accept()函数调用,会从已连接队列中取出一个“连接”。  未完成队列和已完成队列中连接数目之和将减少1。

6,监听套接字的已完成队列中的元素个数大于0,那么该套接字是可读的。

7,当程序调用accept的时候(设置阻塞参数),那么判定该套接字是否可读,不可读则进入睡眠,直至已完成队列中的元素个数大于0(监听套接字可读)而唤起监听进程。

 

从网上找了一段验证该机制的代码:额,结果,我不能理解。。。

#include 
#include
#include
/* basic system data types */ #include
/* basic socket definitions */ #include
/* sockaddr_in{} and other Internet defns */ #include
/* inet(3) functions */// #include
/* epoll function */ #include
#include
#include
#include
#include
int main(int argc,char*argv[]) { int listenfd,connfd; struct sockaddr_in cliaddr,servaddr; int queuelen; 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(12989); 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; }----------------------------------------华丽分割线--------------------------------------------------- #include
#include
#include
/* basic system data types */ #include
/* basic socket definitions */ #include
/* sockaddr_in{} and other Internet defns */ #include
/* inet(3) functions */// #include
/* epoll function */ #include
#include
#include
#include
#include
//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(12989); int i; for(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; }

上部分是服务端,下部分是客户端。

服务端执行:     ./server 2

客户端执行:      ./client

 

执行结果:

pid#1962174 connected...pid#1871924 connected...pid#1146952 connected...pid#1585294 connected...pid#1962174 exit...pid#1146952 exit...pid#1871924 exit...pid#1585294 exit...connect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outconnect error: Connection timed outpid#2064532 exit...pid#1749096 exit...pid#1052892 exit...pid#1077410 exit...pid#782454 exit...pid#1261572 exit...pid#602162 exit...pid#1761490 exit...pid#1409108 exit...pid#1687662 exit...pid#897224 exit...pid#1720342 exit...pid#1765402 exit...pid#1830952 exit...pid#2019546 exit...pid#2085100 exit...end of wait: No child processes

立刻建立了4个连接。

怎么理解呢?

我的执行环节为AIX 6.1.0.0

 

转载于:https://www.cnblogs.com/zhangyabin---acm/p/3998475.html

你可能感兴趣的文章
MD5,SHA256,时间戳获取
查看>>
Linux下安装JDK
查看>>
P1537 弹珠 布尔背包
查看>>
ASP.NET控件Button (e.CommandArgument的使用方法)
查看>>
React Native windows搭建记录
查看>>
Cogs 329. K- 联赛(最大流)
查看>>
【C++】static关键字的总结
查看>>
AngularJs+bootstrap搭载前台框架——js控制部分
查看>>
通过AutoExpand调试Unreal内置数据类型
查看>>
vue-resource
查看>>
android监听返回按钮
查看>>
运输层和TCP/IP协议
查看>>
DBX Error: Driver could not be properly initialized..解决办法
查看>>
[转帖] Linux运维基础知识学习内容
查看>>
手机浏览器一键跳转微信公众号关注的方法
查看>>
如何使用 VS2015 进行远程调试?
查看>>
EL表达式
查看>>
博客页面练习
查看>>
NOI 4978 宠物小精灵之收服(二维背包)
查看>>
配置信息写入到.ini文件中的方法
查看>>