ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

2022-05-02-Linux C 中listen函数用法及注意事项

2022-05-02 13:34:36  阅读:282  来源: 互联网

标签:02 socket 05 队列 内核 2022 接字 连接 backlog


Linux C 中listen函数用法详细介绍及注意事项:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:int listen(int sockfd, int backlog);
服务端程序 监听来自客户端的tcp socket的连接请求 调用listen导致服务端创建的服务端套接字socket从CLOSED状态转换到LISTEN状态。

sockfd:一个已绑定未被连接的套接字描述符;
backlog:第二个参数是等待连接队列的最大长度,比方说,你将backlog定为10, 当有15个连接请求的时候,前面10个连接请求就被放置在请求队列中,后面5个请求被拒绝。
千万要注意:这个10并不是表示客户端最大的连接数为10, 实际上可以有很多很多的客户端来连接(实践证明也是如此)。

参数backlog定义内核监听队列的最大长度。 在进程正在处理一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,
有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队
列以跟踪这些完成的连接但服务器进程还没有接手处理的连接(还没有调用accept函数的连接),这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个
backlog告诉内核使用这个数值作为上限。

backlog:APUE中指出,backlog只是一个提示,具体的数值实际上由系统决定。在内核版本2.2之前的Linux中,backlog参数是指所有处于半连接状态(SYN_RCVD)和完全连接
状态(ESTABLISHED)的socket的和的上限。但自内核版本2.2之后,它只表示处于完全连接状态的socket的上限,处于半连接状态的socket的上限则
由/proc/sys/net/ipv4/tcp_max_syn_backlog内核参数定义。backlog参数的典型值是5(4.2BSD支持的最大值)。

当socket函数创建一个套接字时,它被假设为一个主动套接字,也就是说,它是一个将调用connect发起连接的客户端套接字。listen函数把一个未连接的套接字(服务端套
接字)转换成一个被动套接字,指示内核应接受指向该套接字的连接请求。根据TCP状态转换图,调用listen导致服务端套接字sockfd从CLOSED状态转换成LISTEN状态。
listen函数把进程变为一个服务器,并指定相应的套接字sockfd(服务端socket)变为被动连接。

成功: 0;失败:-1;并设置errno。
EADDRINUSE:另一个socket也在监听同一个端口。
EBADF:参数sockfd为非法的文件描述符。
ENOTSOCK:参数sockfd不是文件描述符。
EOPNOTSUPP:套接字类型不支持listen操作。

内核为任何一个给定的监听套接字维护两个队列:
(1)未完成连接队列。每个这样的SYN分节对应其中一项:已由某个客户端程序发出并到达服务器,而服务器正在等待完成相应的TCP三次握手过程。这些套接字处于SYN_ RCVD状态。
(2)已完成连接队列。每个已完成TCP三次握手过程的客户端程序对应其中一项,这些套接字处于ESTABLISHED状态。

客户端与服务器-socket通信流程交互图:

TCP三次握手:

涉及到的维护的两个队列:

查看系统默认backlog:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog

改变系统限制的backlog 大小:
vim /etc/sysctl.conf

最后添加:
net.core.somaxconn = 1024 net.ipv4.tcp_max_syn_backlog = 1024

保存,然后执行:
sysctl -p

1)为什么全连接队列设置大小为16, 而最终ESTABLISHED的个数为17, 多个数值尝试都为+1的关系?
切换到全连接队列的处理逻辑是这样子的: 先判断全连接队列是否已满, 再执行++操作; 如果backlog为16, 第16个ACK(第三次握手)到来时, 全连接队列实际大小为15, 未满, 则++, 此
时才为16; 第17个ACK到来时, 实际大小为16, 而判断逻辑是>, 未满, 又++, 此时为17, 后续的就满了, 符合+1的逻辑关系.

半连接队列-1,全连接队列+1:

标签:02,socket,05,队列,内核,2022,接字,连接,backlog
来源: https://www.cnblogs.com/YiMingXiaoBuYiMengXiaoNai/p/Linux-C-listen-function.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有