音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

Python 聊聊socket中的listen()参数(数字)到底代表什么
日期:2021-09-08 14:05:13   来源:脚本之家

疑问

在调用socket的时候,我们会使用到listen()函数,里面有个参数叫backlog, 例如:socket.listen(5). 那么这个数字5到底代表什么意思呢?网上有很多种说法,讲的都是概念,很多都是复制粘贴,容易让人误解。

解答

下面使用具体的代码片段来讲解:

这是一个电脑本机模拟客服端及服务端的程序,主要功能是建立socket连接后,客户端输入关键字查询对应的段子,服务器端返回结果。服务器可以满足同时服务两个客户的查询操作此程序中还包含了信号量和多线程

以listen(1),参数设置为1进行讲解,是不是将参数设置为1后,开启3个客服连接就会报错呢?并不是!

如下图所示:

那么问题来了!

问题1:

如上例代码中,有listen(1),这个1是指什么?只能与1个socket建立链接吗? 为什么我用上面的代码可以创建大于1个的tcp连接却没报错,如果用网上其他人的说法理论上大于1个连接应该报错的!

因为:listen(n)传入的值, n表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。n也可以看作是"排队的数量"

问题2:

既然没有报错,为什么没有打印用户3的地址?

因为:服务器正在处理用户1和用户2,没有空闲去接待用户3,所以用户3去排队了。

问题3:

为什么服务器能同时处理用户1和用户2?

因为:

这里用到了多线程和信号量,信号量设置为2,也就是允许并发数为2,服务器开启了两个线程,能同时分别处理用户1和用户2。

总结

socket.listen(n)

简单来说,这里的nt表示socket的”排队个数

一般情况下,一个进程只有一个主线程(也就是单线程),那么socket允许的最大连接数为: n + 1如果服务器是多线程,比如上面的代码例子是开了2个线程,那么socket允许的最大连接数就是: n + 2换句话说:排队的人数(就是那个n) + 正在就餐的人数(服务器正在处理的socket连接数) = 允许接待的总人数(socket允许的最大连接数)

补充:关于Socket.listen方法的一点体悟

前言

最近在接触Socket的的时候,关于其中的listen方法感到不解,于是对其进行了一番研究,得出了一点体悟,特此记录。

详解

让我们先来看看listen方法在Python3.6文档说明:

socket.listen([backlog])

Enable a server to accept connections. If backlog is specified, it must be at least 0 (if it is lower, it is set to 0); it specifies the number of unaccepted connections that the system will allow before refusing new connections. If not specified, a default reasonable value is chosen.

启用服务器以接受连接。如果指定backlog,则必须至少为0(如果低于0,则设置为0);它指定系统在拒绝新连接之前将允许的未接受连接的数量。如果未指定,则选择默认的合理值。

Changed in version 3.5: The backlog parameter is now optional.

在版本3.5中已更改: backlog参数现在是可选的。

起初我看了这说明想当然的以为是可以接入的Client上限,不过实践过后发现并非如此。在网上找的解答基本上就是文档所言的复述,后来请教了专业人士后,方知这涉及到Socket的底层知识。

在了解listen方法之前,首先我们需要了解connect方法和accept方法,以下是文档说明:

socket.connect(address)

Connect to a remote socket at address. (The format of address depends on the address family — see above.)

在地址连接到远程套接字。(地址的格式取决于地址系列 - 请参见上文)

If the connection is interrupted by a signal, the method waits until the connection completes, or raise a socket.timeout on timeout, if the signal handler doesn't raise an exception and the socket is blocking or has a timeout. For non-blocking sockets, the method raises an InterruptedError exception if the connection is interrupted by a signal (or the exception raised by the signal handler).

如果连接被信号中断,则该方法等待直到连接完成,或者如果信号处理程序没有引发异常并且套接字正在阻塞或者已经阻塞,则在超时时引入socket.timeout超时。对于非阻塞套接字,如果连接被信号中断(或由信号处理程序引发的异常),则该方法引发InterruptedError异常。

Changed in version 3.5: The method now waits until the connection completes instead of raising an InterruptedError exception if the connection is interrupted by a signal, the signal handler doesn't raise an exception and the socket is blocking or has a timeout (see the PEP 475 for the rationale).

在版本3.5中已更改:该方法现在等待直到连接完成,而不是提高InterruptedError异常,如果连接被信号中断,信号处理程序不引发异常,套接字阻塞或超时(参见 PEP 475)。

socket.accept()

Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

接收一个连接.该socket 必须要绑定一个地址和监听连接.返回值是一对(conn, 地址)其中conn是新 t4 > socket对象可用于在连接上发送和接收数据,address是连接另一端的套接字的地址。

The newly created socket is non-inheritable.

新创建的套接字non-inheritable。

Changed in version 3.4: The socket is now non-inheritable.

在版本3.4中更改:套接字现在是不可继承的。

Changed in version 3.5: If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising an InterruptedError exception (see PEP 475 for the rationale).

在版本3.5中更改:如果系统调用中断并且信号处理程序没有引发异常,则此方法现在重试系统调用,而不是引发InterruptedError异常 PEP 475)。

相比listen方法,它俩就好理解多了,一个是Client用于连接Server的方法,一个是Server用于接收Client的连接申请的方法。

但事实上accept方法一次只能接收一个Client的连接申请,而Client则是多个的,这样Socket会设计一个队列来存储Client的连接申请则是理所当然的。于是accept便从这个队列里提取首位成员处理即可。

以下是示意图:

如此便很清晰了,backlog参数的含义便是这个队列的最大值,也就是同时受理连接申请的最大值。关于backlog该设置为多少,从Skynet得到的参考为32。如果满了便需要Client重新connect。以上listen方法之谜便解开了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    ASP编程JSP编程PHP编程.NET编程python编程