网络协议栈中的 SO_REUSEADDR 选项

网络协议栈中的 SO_REUSEADDR 选项

在lwip协议栈中,在tcp.c中有如下代码

    
    
    
    
#if SO_REUSE && SO_REUSE_RXTOALL if ((broadcast || ip_addr_ismulticast( & current_iphdr_dest)) && ((pcb -> so_options & SOF_REUSEADDR) != 0 )) { ………………………… } #endif /* SO_REUSE && SO_REUSE_RXTOALL */

对于其上的两个条件编译选项,其定义在opt.h中

复制代码
    
    
    
    
/* * * SO_REUSE==1: Enable SO_REUSEADDR option. */ #ifndef SO_REUSE #define SO_REUSE 0 #endif /* * * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets * to all local matches if SO_REUSEADDR is turned on. * WARNING: Adds a memcpy for every packet if passing to more than one pcb! */ #ifndef SO_REUSE_RXTOALL #define SO_REUSE_RXTOALL 0 #endif
复制代码

根据SO_REUSEADDR线索,搜索其作用在Richard Stevens的《Unix网络编程指南》卷一里有很详细的解答(中文版P166-168页)。现摘抄如下

复制代码
    
    
    
    
SO_REUSEADDR可以用在以下四种情况下。 (摘自《Unix网络编程》卷一,即UNPv1) 1 、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。 2 、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。 3 、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。 4 、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。
复制代码

注:当两个socket的address和port相冲突,而你又想重用地址和端口,则旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性,只有两者之一有这个特性还是有问题的。

参考文章给出了各个条件下的测试程序。也一并摘录如下

View Code

运行程序,然后telnet localhost 10013,看结果

2.无测试用例

3.

View Code

4.由于第四种情况只用于UDP的多播,和TCP的使用没多大关系,所以就不写测试例子了。

参考文章

《socket编程:SO_REUSEADDR例解》

你可能感兴趣的:(网络协议栈中的 SO_REUSEADDR 选项)