listen函数: 对于listen函数来说,它使用来监听端口的,它用在TCP网络通信当中的服务器角色,UDP和客户端都是不需要它的。当我们在编写网络通信程序时,调用socket函数创建了一个套接字以后,改套接字就对应的和相应的输出缓冲区和输入缓冲区建立了联系,此时改套接字的状态正处于CLOSED(观察TCP状态转换图即可),当我们调用listen函数以后,改套接字的状态就变成了LISTEN监听状态,此时,处于等待客户端连入的状态。
这里的话,主要记录一下listen的第二个参数的意思吧。
对于一个调用listen进行监听的套接字’操作系统会为其维护2个队列:未完成连接队列和已完成连接队列。 (1)未完成连接队列中的连接 当客户端发送TCP连接三次握手的第1次(即SYN包)时,服务器端会在未完成连接队列中创建一个与该SYN包对应的项,可以把该项看成一个半连接(因为连接尚未建立)该半连接的状态会从LISTEN变成SYNRCVD同时向客户端返回第2次握手的包 (SYN’ACK)而此时服务器正在等待完成第3次握手 2)已完成连接队列中的连接 3次握手完成后’该连接就变成ESTABLISHED状态’每个已经完成3次握手的客户端连接(完整说法应该是“服务器端的与客户端对应的socket连接”)都放在这个队列中作为一项。
如下所示:
从上图可以看到客户端发送的三次握手的第1个SYN包从图的下方发送过’在三次握手完成之前’连接都会在未完成连接队列中;三次握手完成后’该连接就从未完成连接队列转移到已完成连接队列。
而listen函数”曾经“的含义为这两个队列的和不超过backlog,实际上由于操作系统的原因可能会比这个值稍微多一些。 而现在由于考虑到syn攻击,backlog参数的含义改为了已连接队列之和,去除了半连接队列之和了。
举一个例子,在socket编程当中,如果我们在服务端不用accept函数,,listen函数的第二个参数设置为5,那么这个时候,可以成功连接的客户端就是最多可以成功连入5个,每连入一个,队列的项数就会加一(减一的话就是用accept函数去取出来),所以当项数达到5时,客户端自然就会连不上了。
|