在没接触过这个问题之前,自然会想到服务器端连接数是由服务器端口号限制的。但这其实是一个很严重的误解,要解决这个问题,必须理解socket的连接过程。

以python为例,tcp服务端socket需要经过如下的初始化步骤:

import socket

# 建立socket对象
s = socket.socket()
# 初始化地址,注意这里用的是一个元组
addr = ("127.0.0.1", 43211)
# 绑定
s.bind(addr)
# 监听
s.listen(5)

这时服务端的socket就准备好了,进到下一步等待connect的阶段:accept。看一下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.

accept会返回一个元组,包含一个新的socket对象和客户端的地址。这个新的对象用于发送或接收数据。

就是说,对于TCP服务端来说,返回的新的socket对象,和最开始用于listen的socket对象是不一样的。也就是说,最开始绑定了端口和主机的socket对象是专门用于接收连接请求的。

我们实际使用一下这个函数:

# 客户端运行
import socket s = socket.socket()
s.connect(("127.0.0.1", 43211))
# 服务端
s.accept()
# (<socket.socket fd=568, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 43211), raddr=('127.0.0.1', 2588)>, ('127.0.0.1', 2588))

再来一遍

# 客户端运行
import socket s = socket.socket()
s.connect(("127.0.0.1", 43211))
# 服务端
s.accept()
# (<socket.socket fd=468, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 43211), raddr=('127.0.0.1', 2823)>, ('127.0.0.1', 2823))

可以看到,每次返回的socket的包含了协议,服务端地址+端口号和客户端地址+端口号。这个五元组唯一标识了这个连接,也就是说限制单机TCP最大连接数的因素,从理论上来说是ip地址范围*端口范围,连接数最多是2^32*2^16=2^48。但实际情况中这个和设备的内存,一条tcp连接占用的内存有关,端口号的范围65535并不是单机服务器处理的连接数上限。

最新文章

  1. java基础算法之插入排序
  2. 利用ajax的方式来提交数据到后台数据库及交互功能
  3. NSCharacter​Set在字符串操作中得使用
  4. 我的AngularJS 学习之旅(二)
  5. mysql 占用的内存大小
  6. SQLite 入门教程(三)好多约束 Constraints
  7. Claris and XOR
  8. 如何把mysql的ID归0?
  9. QTP自动化测试培训:描述编程之WebElement
  10. elasticsearch聚合查询
  11. Sping Boot入门到实战之入门篇(二):第一个Spring Boot应用
  12. C++继承中的public/protected/private
  13. NPOI 修改指定单元格字体颜色
  14. jQuery源码解析对象实例化与jQuery原型及整体构建模型分析(一)
  15. 1131 Subway Map DFS解法 BFS回溯!
  16. C程序设计实践教学提示
  17. sklearn_线性回归
  18. Django - Python3 配置 MySQL
  19. cocos 2dx 通过循环实现界面图形的摆放
  20. mac版IDEA使用maven的问题

热门文章

  1. PHP strip_whitespace() 函数
  2. P5488 差分与前缀和 NTT Lucas定理 多项式
  3. 牛客练习赛63 牛牛的斐波那契字符串 矩阵乘法 KMP
  4. Canal简介
  5. [转]Spring Security架构
  6. day2. 六大基本数据类型简介
  7. 使用Flask开发简单接口(1)--GET请求接口
  8. 从零搭建Spring Boot脚手架(1):开篇以及技术选型
  9. 020_go语言中的接口
  10. Linux学习笔记之配置网络