网络编程实战 15 地址已经被使用

例子

服务端Ctrl + C在服务器关闭连接,重启服务器端程序可能会重启失败,报错信息为:bind failed: Address already in use。

原因:TIME_WAIT

通过服务器端发起的关闭连接操作,引起了一个已有的 TCP 连接处于 TME_WAIT 状态,正是这个 TIME_WAIT 的连接,使得服务器重启时,继续绑定在 127.0.0.1 地址和 9527 端口上的操作,返回了 Address already in use 的错误。

解决:重用套接字选项

 一个TCP通过四元组来唯一确定,如果每次客户端使用的本地端口都不同,就不会和已有的四元组冲突,也就不会有TIME_WAIT新旧连接化身冲突的问题。

 四元组相同时的优化:
●新连接SYN告知的初始序列号,一定比TIME_WAIT老连接的末序列号大,可以通过序列号区别新老连接。

●SO_REUSEADDR套接字选项,允许一个TIME__WAIT的TCP连接忽略掉旧连接,重新被新连接使用。还有一个作用,如果本机服务器有多个地址,可以在不同地址的相同端口提供服务。

int on = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

准则

服务端程序,都应该设置SO_REUSEADDR套接字选项,以便服务端程序可以在极短时间内复用同一个端口启动。可以快速重启

SO_REUSEADDR 套接字选项还有一个作用,那就是本机服务器如果有多个地址,可以在不同地址上使用相同的端口提供服务。

但是TCP不允许在相同的地址和端口绑定不同的服务器,即使设置了SO_REUSEADDR也不行

tcp_tw_reuse 和 SO_REUSEADDR

●tcp_tw_reuse 是内核选项,主要用在连接的发起方。TIME_WAIT 状态的连接创建时间超过 1 秒后,新的连接才可以被复用,注意,这里是连接的发起方(发起方才能进入TIME_WAIT);
 tcp_tw_reuse是为了缩短time_wait的时间,避免出现大量的time_wait链接而占用系统资源,解决的是accept后的问题;

●SO_REUSEADDR 是用户态的选项,SO_REUSEADDR 选项用来告诉操作系统内核,如果端口已被占用,但是 TCP 连接状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而 TCP 处于其他状态,重用端口时依旧得到“Address already in use”的错误信息。注意,这里一般都是连接的服务方
 SO_REUSEADDR是为了解决time_wait状态带来的端口占用问题,以及支持同一个port对应多个ip,解决的是bind时的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值