You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在相同端口上同时创建支持IPv4与IPv6的Socket?

同一端口同时支持IPv4和IPv6 Socket的实现方案

报错原因

默认情况下,大多数Linux/UNIX系统的IPv6套接字未开启IPV6_V6ONLY选项时,会同时监听IPv4和IPv6的连接请求,相当于同时占用了该端口的IPv4、IPv6双栈。你先绑定了IPv4的8888端口,再绑定IPv6的8888端口时,系统会判定端口已被占用,因此抛出Address already in use错误。

两种实现方案

方案1:仅使用单个IPv6套接字(推荐)

不需要分别创建IPv4和IPv6两个套接字,默认配置下的IPv6套接字可以自动兼容IPv4请求,IPv4地址会被映射为::ffff:<IPv4地址>的格式,无需额外处理即可同时响应两种协议的请求,代码更简洁:

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>

int main(int argc , char *argv[])
{
    int socket_desc6;
    struct sockaddr_in6 server6;
    // 只创建IPv6套接字
    socket_desc6 = socket(AF_INET6 , SOCK_STREAM , 0);
    if (socket_desc6 == -1)
    {
        printf("Could not create socket");
        return 1;
    }
    puts("IPv6 Socket created");

    server6.sin6_family = AF_INET6;
    server6.sin6_addr = in6addr_any;
    server6.sin6_port = htons(8888);

    if( bind(socket_desc6,(struct sockaddr *)&server6 , sizeof(server6)) < 0)
    {
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done, support both IPv4 and IPv6");

    listen(socket_desc6 , 3);
    sleep(30);
    return 0;
}

方案2:分开创建两个套接字

如果你确实需要分别处理IPv4和IPv6的连接,可以在绑定IPv6套接字前,通过setsockopt开启IPV6_V6ONLY选项,强制该套接字仅处理IPv6请求,就不会和IPv4套接字的端口冲突。
在你原有代码的「创建IPv6套接字后、绑定操作前」添加如下代码即可:

int opt = 1;
if (setsockopt(socket_desc6, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) < 0) {
    perror("setsockopt IPV6_V6ONLY failed");
    return 1;
}

内容的提问来源于stack exchange,提问作者Anis_Stack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 00:24:00