TCP源端口增加2,即使curl / wget也是如此

当使用curl和wget时,如果没有手动设置源端口(如curl中的–local-port),则源TCP端口将始终为偶数,并将递增2而不是1。

EG:在tcpdump中,当我build立连接时,我看到使用的源端口45080,然后下一个连接将使用45082,而不是45801.使用本地端口我可以强制它使用奇数端口,并确认tcpdump成功使用。

这是在networkingtesting床上引起我的问​​题,我不能在我的生活中找出什么是控制隐式的TCP端口select。 我可以改变范围,但我不能改变“增量”。

使用centos7和“3.10.0-514.el7.x86_64”内核。

在tcpdump中,我看到了使用wget和curl的相同行为,这导致我相信这不是一个curl特定的问题,而是正在用于select端口的机制。

另外,如果我看到使用端口45080curl,例如,我知道下一个端口将使用45082.如果我强制50000的本地端口,然后再curl没有 – 本地端口,它将是45082,就像一个单独的计数器递增它,不受任何“最后”使用的端口是什么影响。

或者,如果做同样的事情,而不是强制端口50000,而不是强制端口50000,我强迫它使用45082,它的端口,它可以挑选,然后我再次使用curl,而不强迫本地端口,它会select45083 ,那么如果再次select45084,那么45086 …

如果我将范围限制到奇数个端口,唯一的方法是自然地select一个奇数。

是否有一个系统调用,或者某种内核操作来拾取源端口,有没有办法改变它?

谢谢!

我相信我能够certificate内核本身就是这样增加端口的。

Strace显示wget和curl都调用connect()而不调用bind()来显式设置源端口。

我写了一个python脚本来模拟同样的事情,看起来3.1内核增加了2,而2.6内核却没有。

有趣的是,只有在使用connect()的情况下,如果绑定在端口0上,才会让内核select下一个可用的端口,这是非常随机的。

我的脚本:

import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('10.28.0.2', 80)) addr = s.getsockname() print addr[1] s.close() 

输出:

 $ python port_test.py 45008 $ python port_test.py 45010 $ python port_test.py 45012