tcp的SO_REUSEADDR和SO_REUSEPORT套接字选项

在Linux网络编程中,SO_REUSEADDRSO_REUSEPORT 是两个常用的套接字选项,它们用于控制套接字的地址复用行为。尽管名称相似,但它们有不同的用途和行为。下面是这两个选项的详细区别和用法:

SO_REUSEADDR

功能
  • 地址复用: 允许在套接字关闭后立即重新绑定到相同的地址和端口,而不需要等待TCP的TIME_WAIT状态结束。
  • 端口复用: 允许多个套接字绑定到同一个地址和端口,但每个套接字必须绑定到不同的接口。
常见用法
  • 服务器重启: 服务器程序在重启时,如果上一个实例刚刚关闭且套接字仍处于TIME_WAIT状态,设置SO_REUSEADDR可以使新实例立即绑定到相同的地址和端口。
  • 多播: 在多播应用中,可以通过设置SO_REUSEADDR来允许多个套接字绑定到同一个多播地址。
示例代码
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int sockfd;
    struct sockaddr_in addr;
    int opt = 1;

    // 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return 1;
    }

    // 设置SO_REUSEADDR选项
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
        perror("setsockopt");
        close(sockfd);
        return 1;
    }

    // 配置地址结构
    addr.sin_family = AF_INET;
    addr.sin_port = htons(12345);
    addr.sin_addr.s_addr = INADDR_ANY;

    // 绑定地址
    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        close(sockfd);
        return 1;
    }

    // 监听连接
    listen(sockfd, 10);

    // 关闭套接字
    close(sockfd);

    return 0;
}

SO_REUSEPORT

功能
  • 端口复用: 允许多个套接字绑定到相同的地址和端口,且这些套接字可以在同一个或不同的进程中。
  • 负载均衡: 内核会将传入的数据包分发给绑定到相同地址和端口的多个套接字,实现负载均衡。
常见用法
  • 多进程服务器: 在多进程服务器应用中,可以通过设置SO_REUSEPORT来使多个进程共享同一个端口,从而实现负载均衡。
  • 多线程服务器: 在多线程服务器应用中,可以通过设置SO_REUSEPORT来使每个线程使用独立的套接字,从而提高并发性能。
示例代码
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int sockfd;
    struct sockaddr_in addr;
    int opt = 1;

    // 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return 1;
    }

    // 设置SO_REUSEPORT选项
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
        perror("setsockopt");
        close(sockfd);
        return 1;
    }

    // 配置地址结构
    addr.sin_family = AF_INET;
    addr.sin_port = htons(12345);
    addr.sin_addr.s_addr = INADDR_ANY;

    // 绑定地址
    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        close(sockfd);
        return 1;
    }

    // 监听连接
    listen(sockfd, 10);

    // 关闭套接字
    close(sockfd);

    return 0;
}

总结

  • SO_REUSEADDR: 解决地址和端口在TIME_WAIT状态下的复用问题,适用于服务器重启和多播应用。
  • SO_REUSEPORT: 允许多个套接字绑定到相同的地址和端口,适用于多进程或多线程服务器的负载均衡。

通过合理设置这两个选项,可以提高网络应用的健壮性和性能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值