socket编程 REUSEADDR/REUSESOCK 参数区别

socket编程 REUSEADDR/REUSESOCK



前言

介绍一下系统调用 setsockopt 的REUSEADDR/REUSESOCK 参数区别。

众所周知,TCP连接中主动断开连接方会进入一个TIME_WAIT 状态,并连接会等待两个MSL时间才真正断开,来防止最后一个发送的ACK丢失也能重发和让数据包在网络中消散。


应用场景

对于一个服务器程序来说,它要服务大量的用户请求,服务器在接受请求进行后续的业务处理时,难免可能出现BUG导致服务器崩溃,此时并不是第一时间定位BUG,而是想办法重启服务来减少服务崩溃无法处理业务带来的损失,而此时服务端为主动断开连接,立即重启服务会发送bind错误,得等待2MSL时间后服务才能重启,setsocket 系统的 REUSEADDR/REUSESOCK 参数都可以解决此类问题,让服务立即重启。


 int opt = 1;
 setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR/* SO_REUSEPORT也可 */, &opt, sizeof(opt));


REUSEADDR/REUSESOCK 的区别

REUSESOCK 可以认为是REUSEADDR的超集,都可以重新绑定处于TIME_WAIT状态的端口,但REUSESOCK功能更强大,REUSESOCK参数还可以重复绑定处理listen状态的端口,并实现负载均衡。

使用同样的代码,起两个简单的echoserver,绑定同一个端口

int main()
{
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    int opt = 1;
    setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = 0;
    addr.sin_port = htons(8080);

    if (-1 == bind(lfd, (sockaddr *)&addr, sizeof(addr)))
    {
        cout << "bind error!" << endl;
        exit(1);
    }

    listen(lfd, 8);

    int fd = accept(lfd, NULL, NULL);

    cout << "new client fd: " << fd << endl;

    char buf[255];
    while (1)
    {
        int rd_count = read(fd, buf, sizeof(buf) - 1);
        if (rd_count > 0)
        {
            int sd_count = write(fd, buf, strlen(buf));
        }
        else if (rd_count == 0)
        {
            cout << "client close socket" << endl;
            close(fd);
            exit(1);
        }
    }
}

可以看到两个连接被分发到了不同的server上

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

necesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值