listen函数和accept函数



listen函数原型:

#include<sys/socket.h>



int listen(int sockfd,int backlog);


参考《Linux高性能服务器编程》上的解释: socket 被命名之后,还不能马上接受客户连接,需要系统调listen用来创建一个监听队列用来存放待处理的客户连接。对于各个参数:sockfd指定被监听的socket,backlog提示内核监听队列的最大长度。

成功时返回0,失败返回-1并设置errno。

 我对这个函数理解是创建一个监听队列,使需要主动连接的sockfd变成被动接受连接状态。当调用了这个函数的时候,socket变成监听套接字,从一个进程变成一个服务器来响应请求。



当套接字正在处理客户端的请求时,有新的请求也处理不了。那么会怎么办呢?


请求队列


参考TCP/IP详解 卷一:

如果对于新的连接请求,该 T C P监听的端点的连接队列中还有空间T C P模块将对S Y N进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文段收到后才会知道这个新连接时。另外,当客户进程的主动打开成功但服务器的应用层还不知道这个新的连接时,它可能会认为服务器进程已经准备好接收数据了(如果发生这种情况,服务器的T C P仅将接收的数据放入缓冲队列)

如果队列满了呢?

如果对于新的连接请求,连接队列中已没有空间, TCP将不理会收到的SYN也不发回任何报文段(即不发回RST)。如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,客户的主动打开最终将超时


通常队列满是由于应用程序或者操作系统繁忙造成的,这样可以防止应用程序对传入的连接进行服务。



backlog的值设置为SOMAXCONN就会由系统来决定请求队列长度(一般较大)。


需要注意的是这里的backlog和系统允许的最大连接数或者并发服务器所能并发处理的客户数没什么关系。因为backlog说明的是已经完成三次握手后在等待应用层接受的最大连接数。


此时socket处于监听状态。但是要接收请求则需accept函数。



accept函数原型:

#include<sys/socket.h>

int accept(int sockfd,struct sockaddr * addr,socklen_t * addrlen);


作用:从listen监听队列中接受一个连接。

sockfd是经过listen调用的监听socket,addr用来获取被接受连接的远端socket地址,该地址长度由addrlen指出。该socket唯一的标识了这个被接受的连接,服务器可通过读写该socket来跟对应的客户端通信。成功返回一个新的连接socket,失败则返回-1并设置errno。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值