套接字,其属性和SO_REUSEADDR选项

时间:2012-07-12 14:08:26

标签: sockets network-programming

我有几个基本问​​题:

1.套接字由协议,本地IP,本地端口,远程IP和远程端口表示。假设客户端和服务器之间存在这种连接。现在当我将另一个客户端绑定到同一本地端口并且ip 时,它被绑定(我使用了SO_REUSEADDR)但是将第二个客户端的操作连接到同一个远程ip和端口失败。所以, 第三个进程是否无法共享同一个套接字?

2.当我们在绑定到本地端口和ip的套接字上调用listen()时,它会侦听连接。当客户端连接时,它会创建一个套接字(比如说A)。它完成3路握手,然后启动一个不同的套接字(比如说B)并删除套接字A(Source)。新的套接字由新的套接字B处理。所以, 什么样的套接字代表一个监听套接字,即什么是远程IP和端口,是套接字A不同于该套接字或只是添加远程IP和端口到监听套接字形式A?

3.我读到 SO_REUSEADDR可以在端口上建立侦听套接字,如果没有套接字监听该端口,并且该端口上的所有套接字和ip都设置了SO_REUSEADDR选项。但是我还遇到了一个文本,其中说如果客户端绑定到端口和ip,另一个客户端无法绑定到它(即使使用了SO_REUSEADDR),除非第一个客户端成功调用connect()没有侦听套接字(它是一个客户端,所以我们没有调用connect())在该端口上,而在此示例中。那么, 为什么不允许另一个客户?

提前致谢。

1 个答案:

答案 0 :(得分:1)

  1. 正确:无法使用相同的协议,本地端口,本地地址,远程端口和远程地址创建两个不同的套接字。没有什么可以分辨出哪个数据包属于哪个套接字!

  2. 侦听套接字没有远程地址和远程端口。没关系,因为与此套接字关联的线路上没有数据包(尚未)。实际上,所有套接字都没有本地或远程地址或端口。仅在bind()(对于本地)和connect() / accept()(对于远程)被调用时才会分配这些属性。

  3. 在套接字上调用connect()listen()之前,服务器(侦听)或客户端套接字之间没有任何区别。他们是一回事。因此,如果两个套接字都没有远程地址或端口,则不允许两个套接字共享相同的协议,本地地址和本地端口,这样更为正确。

    这在实践中不是问题,因为您通常不会在客户端套接字上调用bind(),这意味着{{1}处的短暂端口存在隐式bind() } 时间。这些典型的客户端套接字不能与侦听套接字冲突,因为它们从没有与之关联的地址变为同时具有与它们相关联的本地和远程地址,跳过它们只有本地地址的状态。