TCP server 为什么一个端口可以建立多个连接?
https://segmentfault.com/q/1010000003101541
如果是tcp client用同一个本地端口去连不同的两个服务器ip,连第二个时就会提示端口已被占用。但服务器的监听端口,可以accept多次,建立多个socket;我的问题是服务器一个端口为什么能建立多个连接而客户端却不行呢?
5个回答
TCP server 可以,TCP client 也可以。一个套接字只能建立一个连接,无论对于 server 还是 client。
注意报错消息是:
[Errno 106] (EISCONN) Transport endpoint is already connected
man 2 connect 说得很清楚了:
Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association.
就是说,TCP 套接字最多只能调用 connect 一次。那么,你的监听套接字调用 connect 了几次?
来点有意思的。
一个套接字不能连接两次,并不代表一个本地地址不能用两次,看!*加粗文字加粗文字*
>>> import socket
>>> s = socket.socket()
# since Linux 3.9, 见 man 7 socket
>>> s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s2 = socket.socket()
>>> s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s.bind(('127.0.0.1', 12345))
>>> s2.bind(('127.0.0.1', 12345))
# 都可以使用同一本地地址来连接哦
>>> s.connect(('127.0.0.1', 80))
>>> s2.connect(('127.0.0.1', 4321))
>>> netstat -npt | grep 12345
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:4321 127.0.0.1:12345 ESTABLISHED 18284/python3
tcp 0 0 127.0.0.1:12345 127.0.0.1:4321 ESTABLISHED 4568/python3
tcp 0 0 127.0.0.1:80 127.0.0.1:12345 ESTABLISHED -
tcp 0 0 127.0.0.1:12345 127.0.0.1:80 ESTABLISHED 4568/python3
你们这些有女友的都弱爆了啦 :-(
更新:大家来玩 TCP: 一个人也可以建立 TCP 连接呢 - 依云's Blog
内核是以一个(著名的)5元信息组来标识不同的socket的:源地址、源端口、目的地址、目的端口、协议号。任何一个不同,都不叫“同一个socket”。
首先,TCP链接是可靠的端对端的链接,每个TCP链接由4个要素组成:2组IP地址(本地和远端),2组端口地址(本地和远端)。其中如果需要跟端口信息绑定时,都需要调用bind函数,如果server端针对2个同样的IP、端口组进行同样的绑定时,第2次同样是不成功的。
有个相关的问题: ftp的数据传输,服务器会用20端口主动连接客户端,如果两个客户端同时在一下载东西,那ftp 服务器能用20端口去连接两个ip ?(这时ftp的服务器其实是tcp里的客户端)
不管是服务器还是客户端,建立TCP链接,同一个端口都只能使用一次。
这句话其实是**错的**!
对于TCP协议,要成功建立一个新的链接,需要保证新链接四个要素组合体的唯一性:客户端的IP、客户端的port、服务器端的IP、服务器端的port。也就是说,服务器端的同一个IP和port,可以和同一个客户端的多个不同端口成功建立多个TCP链接(与多个不同的客户端当然也可以),只要保证【Server IP + Server Port + Client IP + Client Port】这个组合唯一不重复即可。
> netstat -a -n -p tcp |grep 9999
tcp 0 0 127.0.0.1:51113 127.0.0.1:9999 ESTABLISHED 2701/nc
tcp 0 0 127.0.0.1:51119 127.0.0.1:9999 ESTABLISHED 2752/nc
上述结果127.0.0.1:9999
中9999端口成功建立两个TCP链接,也就可以理解。
**客户端**发送TCP链接请求的端口,也就是后续建立TCP链接使用的端口,所以一旦TCP链接建立,端口就被占用,无法再建立第二个链接。
而**服务器端**有两类端口:侦听端口 和 后续建立TCP链接的端口。其中侦听端口只负责侦听客户端发送来的TCP链接请求,不用作建立TCP链接使用,一旦侦听到有客户端发送TCP链接请求,就分配一个端口(一般随机分配,且不会重复)用于建立TCP链接,而不是所说的
服务器一个端口能建立多个连接
。
上述描述也比较片面,客户端如何请求及建立链接,服务器端如何侦听及是否分配新随机端口等...应该都可以在应用层面进行控制,所以上述描述可以作为建立TCP链接的一种方式,仅供参考。
一些英文的参考:
How do multiple clients connect simultaneously to one port, say 80, on a server?
TCP : two different sockets sharing a port?
TCP server 为什么一个端口可以建立多个连接?的更多相关文章
- Socket TCP Server一个端口可以有多少个长连接?受到什么影响?linux最大文件句柄数量总结
Socket TCP Server一个端口可以有多少个长连接? 网上答案很多,不知道那个才是正确的 理论上是无限的 16.Linux中,一个端口能够接受tcp链接数量的理论上限是? A.1024 B. ...
- linux服务器apache 一个IP,一个端口,建立多个网站的方法。
找到apache-tomcat-6.0.14\conf\server.xml ,再services 后面添加此段代码: Xml代码 <!-- 此处 新增的项目配置--> <Ser ...
- 一个人也可以建立 TCP 连接呢
今天(恰巧是今天)看到有人在 SegmentFault 上问「TCP server 为什么一个端口可以建立多个连接?」.提问者认为 client 端就不能使用相同的本地端口了.理论上来说,确定一条链路 ...
- [转]一个基于完成端口的TCP Server Framework,浅析IOCP
[转]一个基于完成端口的TCP Server Framework,浅析IOCP http://www.cppblog.com/adapterofcoms/archive/2010/06/26/1187 ...
- Linux TCP server 只能接受一个 TCP 连接
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <str ...
- 基于 LWIP 建立 TCP Server 与主机通信实验
LWIP 版本:2.0.3 上一篇文章是写如何将 LWIP 移植到板子上,今天晚上记录基于 LWIP 实现与主机的网络通信. 先是打开了原子的实验例程,大概浏览了一遍,觉得 TCP 网络网络通信也就是 ...
- swoole之建立 tcp server
一.swoole的安装 参照官网:https://wiki.swoole.com/wiki/page/6.html 二.代码部分 服务端: <?php $host = "127.0.0 ...
- Tomcat目录结构及Tomcat Server处理一个http请求的过程
http://blog.sina.com.cn/s/blog_62cb15980101jh9x.html 1.Tomcat的结构概述 Tomcat服务器是由一系列可配置的组件构成,其核心组件是 ...
- 一个IP能建立的最大连接数是多少?
在探讨这个问题前,我们先假设一种经典的连接模型: Client -> Load Balancer-> RealServer Pool 并且我们假设这里使用NAT模式的负载均衡,在这种模式下 ...
随机推荐
- 从有序矩阵M x N中找出是否包含某一个数,要求时间复杂度为O(M+N)
有序指的是每行从左到右依次变大,每列从上到下依次变大 思路: 从右上顶点开始依次判断当前值与给定值的大小,往左下顶点移动,结束条件是下标超过范围 public class FindNumInOrder ...
- jmeter 生成不重复的手机号
String account = "${__time(yyyyMMdd,)}"+UUID.randomUUID().toString().split("-")[ ...
- Sitecore 8.2 数据库权限设置
在我的一个项目中,客户决定改变基础设施.在这个过程中,我得到了一些新的东西需要学习.在本文中,我将分享有关Sitecore数据库权限的经验. 在将数据库从一个服务器移动到另一个服务器时,您需要检查提供 ...
- c#调用python脚本实现排序(适用于python脚本中不包含第三方模块的情况)
引用:https://www.cnblogs.com/zoe-yan/p/10374757.html 利用vs2017c#调用python脚本需要安装IronPython.我是通过vs2017的工具- ...
- DataTable求列的最大值、最小值、平均值和样本数
与sql聚合函数相似,会屏蔽null table.Compute("max(ColumnName)", "true"); table.Compute(" ...
- kubernetes(k8s) Prometheus+grafana监控告警安装部署
主机数据收集 主机数据的采集是集群监控的基础:外部模块收集各个主机采集到的数据分析就能对整个集群完成监控和告警等功能.一般主机数据采集和对外提供数据使用cAdvisor 和node-exporter等 ...
- 19、localStorage.getItem得到的是[object Object] 的解决方案
实现本地存储,避免刷新页面数据丢失: localStorage.setItem 只能存储字符串, 所以在储存的时候先将对象转换为字符串 localStorage.setItem("local ...
- Linux(Ubuntu)系统下使用crontab定期执行任务
安装cron(Ubuntu系统自带) apt-get install cron 开启crontab日志 默认情况下的日志是没有开启的,我们需要找到 /etc/rsyslog.d/50-default. ...
- kbmmw 中的Boyer-Moore算法
kbmmw 5.10 版本中实现了一个非常好用的字符串搜索算法,即Boyer-Moore算法. 在用于查找子字符串的算法当中,BM(Boyer-Moore)算法是目前被认为最高效的字符串搜索算法, 它 ...
- 逻辑回归 之 Logist 推导
Logist从概率角度认识 可以咱学校教材大二版的<> - 山大版, 来整一波, 为了简化推导形式呢, 这里就假设2个样本空间的形式来展开, 基于(条件概率) 全概率与贝叶斯 作为核心. ...