函数原型:
int listen(int sockfd, int backlog);
当编写服务器时,经常需要限制客户端的连接个数,下面为问题分析以及解决办法:
下面只讨论TCP UDP不做讨论(很少使用到listen函数)
listen函数用法:函数应该在调用socket和bind这两个函数之后,accept函数之前调用。
listen函数作用:让服务器套接字sockfd进入监听状态。
-
返回值:
- 成功返回0;
- 失败返回-1。
-
参数:
- sockfd:套接字,成功返回后进入监听模式,当有新连接并accept后会再建立一个套接字保存新的连接;
- backlog:暂且翻译为后备连接吧!下面详细介绍此参数:
- 当TCP接收一个连接后(三次握手通过)会将此连接存在连接请求队列里面,并对队列个数+1,而backlog为此队列允许的最大个数,超过此值,则直接将新的连接删除,即不在接收新的连接。将这些处于请求队列里面的连接暂记为后备连接,这些都在底层自动完成,底层将连接添加到队列后等待上层来处理(一般是调用accept函数接收连接);
- 当上层调用accept函数接收一个连接(处于请求队列里面的后备连接),队列个数会-1;
- 那么这样一个加一个减,只要底层提交的速度小于上层接收的速度(一般是这样),很明显backlog就不能限制连接的个数,只能限制后备连接的个数。那为啥要用这个backlog呢?主要用于并发处理,当上层没来的及接收时,底层可以提交多个连接;
- backlog的取值范围 ,一般为0-5。
那么,如何才能限制连接个数,而不是后备的连接个数呢?如下:
我们可以关闭处于监听状态的sock。假设我想限制3个连接,在应用层每当accept到一个连接时,定义一个变量var让其+1,当判断有三个连接时关闭sock。然后动态的检测当前的计数值var,当小于3时,再打开此sock,当然这样操作必须使能SO_REUSEPORT(允许重用本地地址),可以通过调用setsockopt函数来使能,问题解决。