当服务器套接字接受客户端套接字时,究竟发生了什么?

Jon*_*ark 8 sockets tcp

我正在研究套接字编程,而服务器套接字accept()让我感到困惑.我为服务器套接字编写了两个方案accept(),请看一下:

  1. 当服务器套接字执行时accept(),它会创建一个新的(客户端)套接字,该套接字绑定到与端口服务器套接字绑定不同的端口.因此套接字通信是通过新绑定端口完成的,服务器套接字(accept()仅用于)正在等待最初绑定端口上的另一个客户端连接.

我认为这不是很正确的答案,因为(1)端口匹配单个进程和(2)套接字接受是内部进程问题,单个进程可以有多个套接字.所以我根据一些stackoverflow答案做了第二个场景:

  1. 当服务器套接字做accept(),它创建了一个新的(客户端)套接字没有绑定到任何特定的端口,并在客户端与服务器进行通信,它使用的端口被绑定到服务器套接字(谁accept()小号连接)和其客户端套接字来实际的通信是由(sourceIP, sourcePort, destIP, destPort)传输级别的TCP头(?)中的元组解决的(这也是可疑的,因为我认为socket是某种应用程序级对象)

这种情况也提出了一些问题.如果套接字通信仍然使用服务器套接字的端口,即客户端向服务器套接字端口发送一些消息,它是否使用服务器套接字的积压队列?我的意思是,客户端的消息如何区分connect()read() or write()?如何解决服务器中的每个客户端套接字,没有任何端口绑定?

如果我的一个场景是正确的,会回答以下问题吗?或者我可能做了两个错误的场景,所以非常感谢你提供正确的答案,或至少一些相关的文本来研究.

Phi*_*yck 6

当你创建一个套接字并在该套接字上执行绑定然后监听时,你所拥有的就是所谓的a listening socket.建立连接时,此套接字基本上克隆到新套接字,并且此套接字称为the servicing socket绑定的端口仍与原始端口相同.

但是这个套接字和之前的侦听套接字之间有一个重要的区别.即它是一部分socket pair.唯一标识连接的是套接字对.因此图中有2个插座用于套接字对,TCP通信通道的两端有2个IP地址和2个端口.在克隆服务套接字期间,TCP内核将分配所谓的a,TCB并在其中存储这2个IP @和2个端口.TCB还包含属于TCB的套接字号.

每次进入TCP段时,都会检查TCP标头以及它是否是SYN,对于SYN,您将建立连接,以便您已经通过,但随后内核将通过其侦听套接字列表.如果它是普通的TCP数据包而不是SYN,则两个端口号都在TCP头中,并且IP @是IP头的一部分,因此使用此信息,内核能够找到属于此TCP连接的TCP.(对于SYN,此信息也存在,但正如我所说,对于SYN,您只需要处理侦听套接字)

简而言之,它是如何运作的.

此信息可在UNIX网络编程中找到:套接字网络API.在那里描述了到套接字的链接,而在其他参考材料中通常没有详细描述,而是通常突出显示TCP的细节.


use*_*421 6

当服务器套接字执行accept()时,它会创建一个新的(客户端)套接字,该套接字绑定到与端口服务器套接字绑定不同的端口.因此套接字通信是通过新绑定端口完成的,服务器套接字(仅适用于accept())正在等待最初绑定端口上的另一个客户端连接.

没有.

我认为这不是很正确的答案

这是一个错误的答案.

因为(1)端口匹配单个进程

这并不意味着任何相关的东西.

(2)套接字接受是内部处理事务

也不是这样.它实际上似乎没有任何意义.

单个进程可以有多个套接字.

这是真的,但它与你的答案错误无关.您的答案错误的原因是因为没有使用第二个端口.

当服务器套接字执行accept()时,它会创建一个未绑定到任何特定端口的新(客户端)套接字

不会.它创建了第二个套接字,它继承了服务器套接字中的所有内容:端口号,缓冲区大小,套接字选项,...除了文件描述符和LISTENING状态之外的所有内容,也许我忘记了其他内容.然后,它将套接字的远程IP:端口设置为客户端的端口,并将套接字置于ESTABLISHED状态.

当客户端与服务器通信时

客户端已与服务器通信.这就是我们创建这个套接字的原因.

它使用绑定到服务器套接字的端口(谁接受()的连接)以及实际通信的客户端套接字由传输级别的TCP头(?)解析(sourceIP,sourcePort,destIP,destPort)元组

这已经发生了.

这也是可疑的,因为我认为socket是某种应用程序级别的对象)

不,不是.套接字是一个内核级对象,具有应用程序级文件描述符以标识它.

如果套接字通信仍然使用服务器套接字的端口,即客户端向服务器套接字端口发送一些消息,它是否使用服务器套接字的积压队列?

否.积压队列用于传入连接请求,而不是数据.传入的数据进入套接字接收缓冲区.

我的意思是,如何在connect()和read()或write()之间区分来自客户端的消息?

因为connect()请求在TCP头中设置特殊位.它的最后部分可以与数据结合.

如何解决服务器中的每个客户端套接字,没有任何端口绑定?

端口绑定在调用时创建套接字时发生accept().你自己发明了这个难题.这不是真的.

如果我的一个场景是正确的,会回答以下问题吗?

它们都不正确.

或者我可能会制作两个错误的场景,所以非常感谢你提供正确的答案,或至少一些相关的文本来研究.

你肯定已经有相关的文本要学习吗?如果不这样做,您应阅读RFC 793或WR Stevens,TCP/IP Illustrated,第I卷,相关章节.你在这里有几个主要的误解.

  • @parsecer数据由元组*{源IP,源端口,目标IP,目标端口}*标识,并且该元组对于连接是唯一的.传入的数据不会进入端口.它转到TCP,从那里到一个套接字. (2认同)