为什么 accept 返回的套接字与参数套接字不同?

3
int accept(int socket, struct sockaddr *restrict address,socklen_t *restrict address_len);

accept 方法接收一个监听的文件描述符(socket),并返回一个连接的文件描述符。当然,它们是不同的。但这两个套接字有相同的端口,为什么它们不同呢?

listen 方法监听连接,如果 TCP 三次握手完成,则该套接字变为可接受状态。在 accept 过程中,如何将监听套接字传输到新的连接文件描述符套接字?

1个回答

7
两个套接字都使用同一个端口,为什么它们不同呢?
因为如果它们相同,您就无法同时处理多个客户端。已接受的套接字还具有对等方IP地址和端口,而监听套接字没有这些信息。
当`accept()`函数调用时,监听套接字并不会“传输”TCP连接到新的套接字文件描述符,而是创建了一个带有连接细节的新套接字。

它并不会“传输”任何东西。它会使用连接细节创建一个新的套接字。也就是说,accept 函数会使用连接细节创建一个新的套接字,并将监听 fd 指向该连接细节? - wwulfric
它使用连接细节创建一个新的套接字。这正是我所说的。没有任何“意味着”的问题。从“和侦听FD”开始的部分对我来说毫无意义。 - user207421
连接详细信息是在listen还是accept中创建的? - wwulfric
不是的。正如你在问题中所说的那样,它们是由三次握手创建的,并放置在后备队列中。在listen()中创建它们毫无意义。因为还没有连接。这是一个奇怪的问题。 - user207421
明白了。根据我的理解,这个问题在某种程度上是合理的,但实际上有些奇怪。 - wwulfric
TCP套接字与本地IP/端口和对等IP/端口相关联。监听套接字没有对等IP/端口,只有本地IP/端口。listen()打开一个后备队列,在本地IP/端口上执行与传入TCP客户端的三次握手。accept()使用监听套接字来知道从哪个队列中拉出连接的TCP客户端,然后返回一个新的套接字,该套接字具有监听IP/端口和客户端IP/端口。使用已接受的套接字发送的任何数据包都会发送到客户端IP/端口,并且使用这两个IP/端口对的任何接收数据包都可以使用已接受的套接字进行读取。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接