Http 多个客户端如何同时连接到服务器上的一个端口(例如80)?

Http 多个客户端如何同时连接到服务器上的一个端口(例如80)?,http,tcp,connection,client-server,port,Http,Tcp,Connection,Client Server,Port,我了解端口工作的基本原理。然而,我不明白多个客户端如何同时连接到端口80。我知道每个客户端都有一个唯一的(用于其机器的)端口。服务器是否从一个可用端口回复到客户端,并简单地声明回复来自80?这是如何工作的?通常,对于每个连接的客户端,服务器都会派生一个子进程与客户端通信(TCP)。父服务器将一个已建立的套接字交给子进程,该套接字将与客户端通信 当您将数据从子服务器发送到套接字时,操作系统中的TCP堆栈会创建一个返回到客户端的数据包,并将“from port”设置为80。首先,“port”只是一个

我了解端口工作的基本原理。然而,我不明白多个客户端如何同时连接到端口80。我知道每个客户端都有一个唯一的(用于其机器的)端口。服务器是否从一个可用端口回复到客户端,并简单地声明回复来自80?这是如何工作的?

通常,对于每个连接的客户端,服务器都会派生一个子进程与客户端通信(TCP)。父服务器将一个已建立的套接字交给子进程,该套接字将与客户端通信

当您将数据从子服务器发送到套接字时,操作系统中的TCP堆栈会创建一个返回到客户端的数据包,并将“from port”设置为80。

首先,“port”只是一个数字。“到端口的连接”真正代表的是一个数据包,该数据包的“目的端口”头字段中指定了该编号

现在,您的问题有两个答案,一个用于有状态协议,另一个用于无状态协议

对于无状态协议(即UDP),没有问题,因为“连接”不存在——多个人可以将数据包发送到同一端口,他们的数据包将以任何顺序到达。没有人处于“连接”状态

对于有状态协议(如TCP),连接由一个由源和目标端口以及源和目标IP地址组成的4元组标识。因此,如果两台不同的机器连接到第三台机器上的同一端口,则会有两个不同的连接,因为源IP不同。如果同一台机器(或NAT后面的两台机器或共享相同IP地址的两台机器)两次连接到一个远程终端,则会根据源端口(通常为随机高编号端口)区分连接

简单地说,如果我从客户端两次连接到同一个web服务器,这两个连接将从我的角度具有不同的源端口,从web服务器的角度具有不同的目标端口。因此,即使两个连接具有相同的源和目标IP地址,也没有歧义


端口是多路复用IP地址的一种方式,以便不同的应用程序可以侦听同一IP地址/协议对。除非应用程序定义自己的高级协议,否则无法多路复用端口。如果使用相同协议的两个连接同时具有相同的源和目标IP以及相同的源和目标端口,则它们必须是相同的连接。

重要提示:

很抱歉,来自“Borealid”的回答不准确,而且有些不正确——首先,回答这个问题与状态或无状态无关,最重要的是,套接字的元组定义不正确

首先记住以下两条规则:

  • 套接字的主键:套接字由
    {SRC-IP,SRC-PORT,DEST-IP,DEST-PORT,PROTOCOL}
    标识,而不是由
    {SRC-IP,SRC-PORT,DEST-IP,DEST-PORT}
    标识。协议是套接字定义的重要部分

  • OS进程和套接字映射:一个进程可以与(可以打开/可以侦听)多个套接字相关联,这对于许多读者来说是显而易见的

  • 示例1:两个客户端连接到同一服务器端口意味着:
    socket1{SRC-A,100,DEST-X,80,TCP}
    socket2{SRC-B,100,DEST-X,80,TCP}
    。这意味着主机A连接到服务器X的端口80,另一台主机B也连接到同一台服务器X的端口80。现在,服务器如何处理这两个套接字取决于服务器是单线程还是多线程(我将在后面解释)。重要的是,一台服务器可以同时侦听多个套接字

    回答帖子的原始问题:

    无论是有状态协议还是无状态协议,两个客户端都可以连接到同一个服务器端口,因为我们可以为每个客户端分配不同的套接字(因为客户端IP肯定会不同)。同一个客户端也可以有两个套接字连接到同一个服务器端口,因为这样的套接字不同于
    SRC-port
    。平心而论,“Borealid”基本上提到了相同的正确答案,但提到“州少/州满”有点不必要/令人困惑

    回答问题的第二部分:服务器如何知道要回答哪个套接字。首先要了解,对于侦听同一端口的单个服务器进程,可能有多个套接字(可能来自同一个客户端,也可能来自不同的客户端)。现在,只要服务器知道哪个请求与哪个套接字关联,它就可以始终使用相同的套接字响应相应的客户端。因此,服务器不需要在自己的节点中打开客户端最初尝试连接的原始端口以外的其他端口。如果任何服务器在绑定套接字后分配不同的服务器端口,那么我认为服务器是在浪费资源,它必须需要客户端再次连接到分配的新端口

    更完整一点:

    示例2:这是一个非常有趣的问题:“一台服务器上的两个不同进程可以监听同一端口吗?”。如果您不把协议看作是定义参数的套接字之一,那么答案是否定的。这是因为,我们可以说,在这种情况下,试图连接到服务器端口的单个客户端将没有任何机制来提及客户端打算连接的两个监听进程中的哪一个。这与规则(2)所断言的主题相同。然而,这是错误的答案,因为“协议”也是套接字定义的一部分。因此,同一节点中的两个进程只有在使用不同协议时才能侦听同一端口。例如,两个不相关的客户端(例如一个使用TCP,另一个使用UDP)可以连接到同一个服务器节点和同一个服务器节点并进行通信
        Local Computer    | Remote Computer
        --------------------------------
        <local_ip>:80     | <foreign_ip>:80
    
        ^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
    
        Local Computer   | Remote Computer           | Role
        -----------------------------------------------------------
        0.0.0.0:80       | <none>                    | LISTENING
        127.0.0.1:80     | 10.1.2.3:<random_port>    | ESTABLISHED
    
        netstat -atnp | grep -i ":500 "
    
        sudo python3 -m http.server 500
    
        Proto Recv-Q Send-Q Local Address           Foreign Address         State  
        tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      - 
    
        quicknet -m tcp -t localhost:500 -p Test payload.
    
        Proto Recv-Q Send-Q Local Address           Foreign Address         State  
        tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
        tcp        0      0 192.168.1.10:500        192.168.1.13:54240      ESTABLISHED -
    
        Proto Recv-Q Send-Q Local Address           Foreign Address         State  
        tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
        tcp        0      0 192.168.1.10:500        192.168.1.13:26813      ESTABLISHED -