我正在研究C语言中的套接字编程。在TCP通信中,一个典型的情况是,一旦服务器接受()来自客户端的connect()请求,它将分叉一个新进程来处理这种通信。然后子进程将使用另一个端口与客户端通信。我的问题是,服务器如何通知客户端它将使用另一个端口而不是原始端口来进行后续通信? TCP报头中的哪个字段以及握手的哪个阶段可以反映端口更改?
例如,服务器A上的进程PA正在侦听其端口80.现在,客户端B上的进程PB想要连接到A的端口80.一旦PA接受PB的连接请求,它将分叉一个新进程PA1来处理通信与PB。我到现在为止?接下来,PA1仍然会使用端口80或其他端口(如1234)与PB通信吗?如果仍然使用80,服务器A如何将PB的通信分配给PA1?如果它使用另一个端口,如1234,服务器A将如何通知PB使用1234进行后续通信?
答案 0 :(得分:1)
TCP连接由元组唯一标识(源IP,源端口,目标IP,destinatin端口)。操作系统使用这些元组来绑定"绑定"与进程的TCP连接,意味着知道操作系统应该将TCP包传递到哪个进程。
当服务器套接字接受TCP连接和分支时,该进程继承原始进程,因此它有效地占用了TCP连接到这个新分叉进程的绑定。远程机器中的客户端不知道也不需要知道这种情况发生。整个网络看到同样的事情,同一元组的包流经网络。
此时,原始进程将继续侦听新的TCP连接。当新的TCP连接请求到达时,即使它来自同一台上一台机器,端口也必须不同。在操作系统的角度来看,它是一个不同的元组,因此它可以区分TCP pcakge并传递到正确的过程。
您可能会问为什么来自远程计算机的客户端知道它必须使用另一个端口来启动新连接。这只是因为客户端操作系统知道(或通过套接字库通知)此进程正在创建单独的新连接。操作系统将为进程分配另一个唯一的端口号。这就是多个进程如何在没有消息混乱的情况下与同一服务器端口通信的可能性。
简而言之,服务器中的accept和fork的操作只是将TCP连接绑定的所有权转移到另一个进程。此通信中使用的服务器端口没有任何变化。
答案 1 :(得分:0)
在TCP通信中,一个典型的情况是,一旦服务器从客户端接受()一个connect()请求,它将分叉一个新进程来处理这种通信。
纠正或启动一个帖子。
然后子进程将使用另一个端口与客户端进行通信。
没有。它将使用相同的端口,通过接受的套接字,在子进程的情况下继承。
我的问题是,服务器如何通知客户端它将使用另一个端口而不是原始端口来进行后续通信?
没有,因为这不是“经典情况”。
TCP标头中的哪个字段以及握手的哪个阶段可以反映端口更改?
无。它不会那样发生。这将浪费港口。
例如,服务器A上的进程PA正在侦听其端口80.现在,客户端B上的进程PB想要连接到A的端口80.一旦PA接受PB的连接请求,它将分叉一个新进程PA1来处理通信与PB。我到现在为止?
是
接下来,PA1是否仍然使用端口80或其他端口(如1234)与PB进行通信?
80号港口。
如果仍然使用80,服务器A如何将PB的通信分配给PA1?
继承已接受的套接字。
如果它使用另一个端口,如1234,服务器A将如何通知PB使用1234进行后续通信?
不会发生。
答案 2 :(得分:-1)
客户端选择此端口,而不是服务器。客户端将选择一个尚未在该特定计算机上使用的端口,并使用该端口将其连接分开(就像服务器一样)。
例如,客户端的IP地址为1.2.3.4,服务器的IP地址为4.3.2.1,并在端口80上侦听。如果客户端有两个与该服务器和端口的连接,它将如何区分它们?简单 - 它为每个源端口分配不同的源端口。假设一个获得端口50001,一个获得端口50002,那么这两个连接是:
1.2.3.4:50001 - > 4.3.2.1:80
和
1.2.3.4:50002 - > 4.3.2.1:80
服务器知道这些端口,因为它从客户端发送到服务器的TCP SYN数据包中获取它们。所以客户端告诉服务器,而不是相反。