这是一个花了我三个小时时间才解决的bug。
bug是这样发生的:我写了一个服务器,负责从VDE上接受数据,进行fast压缩之后再推送给其他人写的服务。其他的人写的服务不停都尝试重新连接我的监听端口。因为我的服务在每一天晚上是停止对外服务的,只在VDE有了数据之后才对外服务。发送股票的市场状态。某一天早上,我起程序的时候,发现接收到了一个abort的signal。
于是我尝试跟踪它,跟踪的过程很崩溃,反正用printf大法,我看到崩溃的位置。很普通的语句,就是给一个套接字绑定监听的ip和端口的地方。
okay,端口已经被其他进程占用了。
从这里可以看到:
这就是一个典型的自连接。
因为意料之外的自连接的存在,导致原本的服务端口被占用。
内核的参数net.ipv4.ip_local_port_range决定了本地使用的端口范围。而一个晚上的Reconnect导致,产生了一个自连接。
这个问题,曾经在linux kernel maillist中大家关注过,参见
这个行为是合法的。
出现的概率可能很低,也可能很高。
根据三次握手:
- 总结: 上面的邮件列表提到了自连接很可能是一个合法,但是出乎程序员意料之外的连接。因为在没有监听套接字的前提下,产生了local和peer完全一样的连接。本文我提到了,我的服务正好需要绑定这个端口。所以对我来说是一个意料之外的情况。我觉得解决这个问题最简单的方法是在断线自动重连的逻辑上加上几句代码,判断是否local和peer的端口是否一样,一样就重新连接。