我正在研究套接字编程,服务器套接字 accept()
令我困惑 . 我为服务器套接字 accept()
写了两个场景,请看一下:
- 当服务器套接字执行
accept()
时,它会创建一个新的(客户端)套接字,该套接字从端口服务器套接字绑定到端口 different . 因此套接字通信是通过新绑定端口完成的,服务器套接字(仅适用于accept()
)正在等待原始绑定端口上的另一个客户端连接 .
我认为这不是很正确的答案,因为(1)端口匹配单个进程和(2)套接字接受是内部进程问题,单个进程可以有多个套接字 . 所以我根据一些stackoverflow答案做了第二个场景:
- 当服务器套接字执行
accept()
时,它会创建一个新的(客户端)套接字 not 绑定到任何特定端口,当客户端与服务器通信时,它使用绑定到服务器套接字的 the port (谁accept()
的连接)和 which client socket 来实际通信是通过传输级别的TCP头(?)来解决(sourceIP, sourcePort, destIP, destPort)
元组(这也是可疑的,因为我认为socket是某种应用程序级对象)
这种情况也提出了一些问题 . 如果套接字通信仍然使用服务器套接字's port, i.e. client sends some messages to server socket port, doesn' t它使用服务器套接字的积压队列?我的意思是,如何区分来自客户的消息 connect()
和 read() or write()
?如何解决服务器中的每个客户端套接字,没有任何端口绑定?
如果我的一个场景是正确的,会回答以下问题吗?或者我可能做了两个错误的场景,所以非常感谢你提供正确的答案,或至少一些相关的文本来研究 .
3 回答
没有 .
这是一个错误的答案 .
这并不意味着任何相关的东西 .
也不是这样 . 它实际上似乎没有任何意义 .
这是真的,但它与你的答案错误无关 . 您的答案错误的原因是因为没有使用第二个端口 .
不会 . 它创建了第二个套接字,它继承了服务器套接字中的所有内容:端口号,缓冲区大小,套接字选项,...除了文件描述符和LISTENING状态之外的所有内容,也许我忘记了其他内容 . 然后,它将套接字的远程IP:端口设置为客户端的端口,并将套接字置于ESTABLISHED状态 .
客户端已与服务器通信 . 这就是我们创建这个套接字的原因 .
这已经发生了 .
不,不是 . 套接字是一个内核级对象,具有应用程序级文件描述符以标识它 .
否 . 积压队列用于传入连接请求,而不是数据 . 传入的数据进入套接字接收缓冲区 .
因为
connect()
请求在TCP头中设置了特殊位 . 它的最后部分可以与数据结合 .端口绑定发生在调用
accept()
时创建套接字的那一刻 . 你自己发明了这个难题 . 这不是真的 .它们都不正确 .
你肯定已经有相关的文本要学习吗?如果不这样做,您应阅读RFC 793或W.R. Stevens,TCP / IP Illustrated,第I卷,相关章节 . 你在这里有几个主要的误解 .
当你创建一个套接字并在该套接字上进行绑定然后监听时,你所拥有的就是所谓的
listening socket
. Build 连接时,此套接字基本上克隆到新套接字,并且此套接字称为the servicing socket
,它绑定的端口仍与原始端口相同 .但是这个套接字和之前的侦听套接字之间有一个重要的区别 . 即它是
socket pair
的一部分 . 唯一标识连接的是套接字对 . 因此图中有2个插座用于套接字对,TCP通信通道的两端有2个IP地址和2个端口 . 在克隆服务套接字期间,TCP内核将分配所谓的TCB
,并在其中存储这2个IP @和2个端口 . TCB还包含属于TCB的套接字号 .每次进入TCP段时,都会检查TCP标头以及它是否是SYN,对于SYN,您将 Build 连接,以便您已经通过,但随后内核将通过其侦听套接字列表 . 如果它是普通的TCP数据包而不是SYN,则两个端口号都在TCP头中,并且IP @是IP头的一部分,因此使用此信息,内核能够找到属于此TCP连接的TCP . (对于SYN,此信息也存在,但正如我所说,对于SYN,您只需要处理侦听套接字)
简而言之,它是如何运作的 .
此信息可在UNIX网络编程中找到:套接字网络API . 在那里描述了到套接字的链接,而在其他参考材料中通常没有详细描述,而是通常突出显示TCP的细节 .
从Linux程序员手册,通过
man 2 accept
找到 . Link所以会发生什么是你有一个侦听TCP套接字 . 有人要求
connect()
.然后你调用
accept()
. 旧的侦听套接字仍处于侦听模式,而新的套接字则以连接模式创建 . 端口是原始侦听端口 .这不会干扰侦听套接字,因为新套接字不会侦听传入连接 .