多个客户端如何同时连接到服务器上的一个端口,比如80?(译)
原文:How do multiple clients connect simultaneously to one port, say 80, on a server? [duplicate]
平时我们使用ServerSocket指定了某个端口(例如8080),然后多个客户端连接上socket之后就都用这个8080端口和服务器端通讯。或者http服务器使用80端口也是和多个浏览器进行连接通讯。为什么可以这样呢?操作系统的进程在同个端口的多个连接是如何进行分辨的?
译文:
我们这里讲Socket连接:
1. 端口只是一个数字辨识,不是真正的物理端口;
2. 一个Socket连接的主键(即不同socket之间的区分)是由一个五元组{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}组成,即{源地址,源端口,目标地址,目标端口,协议}组成,那些说四元组不包含协议的说法是错误的。
3. 一个进程可以拥有多个socket连接。
例子一、两个客户端连接在同个服务器的同个端口80,即有两个socket连接:
- socket1 {SRC-A, 100, DEST-X,80, TCP}
- socket2{SRC-B, 100, DEST-X,80, TCP}
主机A和主机B的地址不同,两台主机同时连接到服务器X的80端口。服务器要怎么处理这个连接是它的事,我们要理解的是为什么一个主机同个端口能监听多个客户端Socket连接。
解释:
1. 是因为两个客户端的IP不同,服务器能识别出不同的Socket;
2. 即使IP地址相同,端口不同,服务器也能够分辨;
3. 只要服务器知道收到的请求和哪个socket相关,那么它就能使用这个socket正确地回复那个客户端;
4. 如果对于不同的socket需要不同的端口,那么不仅仅浪费服务器资源,而且每次客户端连接上serverSocket之后还要另外分配新的端口和客户端通信。没必要。
例子二、不同的进程可以监听同一个端口。
因此在服务器的两个使用不同协议的进程可以监听同一个端口。
如果一个socket的辨识只是四元组不包括协议{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT},那么不同进程是不可能同时监听同一个端口的。没有协议的话一个客户端连接到同一台某个有两个进程监听端口的服务器,那么就没有什么机制可以确定客户端是要连接哪一个进程了。
操作系统(特别是UNIX)中,子进程能够继承父进程的所有文件描述File-descriptors (FD),因此父进程A中监听着的所有socket,也可以被进程的所有子进程A1,A2监听。但是不同进程B是不能监听同一个端口的。
个人理解:
1 问题:多个客户端如何同时连接到服务器上的一个端口,比如80?
答:服务器和不同的客户端进行通信,是通过80端口进行通信的。一个套接字是有五元组的{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL},服务端监听80端口号,收到连接请求后,根据客户端的ip和端口号+服务端IP和80端口号+协议创建套接字,然后可以创建一个线程或一个协程通过刚才创建的套接字来和客户端通信。
2 问题:多个客户端同时连接到服务器上的一个端口(比如80),服务器是否会新起另一个端口进行通信?
答:服务器不会新起端口。服务器的80端口一直负责监听客户端的请求,如果有客户端请求,服务器始终使用相同的初试套接字来响应(不需要分配另一个服务器端口),接着创建新的套接字(根据五元组),然后创建一个线程或一个协程通过刚才新创建的套接字来和客户端通信。所以服务器从头到尾只占用了一个80端口进行监听和通信。
3 问题:如果有十万个客户端同时连接服务器,一个80端口是否能容纳这么多客户端连接进行交互?
答:一个80端口是否能容纳和这么多客户端交互,这就是机器性能和程序性能的问题了。
参考: