一场Socket四次握手引发的血案

一场Socket四次握手引发的血案

前奏

Hello Everybody,原谅我是一个标题党。事情是这样的,周末,同事在微信上抛来一个问题,原文如下:

服务端某个服务timewait过多,网上说端口会耗尽,我怎么感觉是fd会耗尽呢,因为一个服务通常只使用一个端口

在记忆的某个角落里,翻出了四次握手的状态图,虽然模模糊糊,但是还是有点印象。


首先,明确一点,主动关闭socket的一端进入timewait阶段,一个socket连接由五元组(目的IP,目的Port,源IP,源Port,协议)唯一标识。对于采用TCP协议的服务端,目的IP目的Port协议这三个元素固定不变,对于同一个客户端来说,其源IP固定不变,也就是说唯一能变的就是源Port。而源Port最大为65535,因此有耗尽的可能,第一次回答如下:

五元组(目的IP,目的Port,源IP,源Port,协议),同一个客户端,目的IP、目的Port、源IP、协议不变,端口有数量限制,因此应该是客户端端口会耗尽。

同事紧接着发难:

先只考虑服务端,timewait过多会导致啥情况?

回忆了一下timewait的作用,隐隐约约记得,防止客户端的FIN包积压在链路中,导致socket错乱。即客户端关闭连接后,重用本次五元组;迟来的FIN包影响新连接。使用timewait,锁定五元组(客户端不能重用本次五元组),使得本次会话的所有数据包在链路中消亡。因而,猜想timewait要维护连接状态,fd不会被释放。第二次回答:

timewait 时候fd被霸占,量大后,fd肯定会被耗尽。

作答后,久久不能平静,因为后半截回答主要靠猜想,没有实际论证,总感觉没有把握,于是开始了一系列的论证过程。

论证

Socket 代码

这里仅列出主要代码逻辑,完整代码参加GitHub

/* server code */
while (1) {
int len = sizeof(struct sockaddr);
fd = accept(sfd, &remote, &len);

res = read(fd, buf, sizeof(buf));
printf("user data : %s\n", buf);

strcpy(buf, "Hello Client");
res = write(fd, buf, sizeof(buf));
printf("send data : %s\n", buf);
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值