为具有相同端口的 ipv6 和 ipv4 创建套接字

create socket for both ipv6 and ipv4 with the same port

我想为具有相同端口的 ipv4 和 ipv6 创建一个套接字。我为此使用了以下 C 代码:

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

int main(int argc , char *argv[])
{
    int socket_desc , client_sock , c , read_size;
    int socket_desc6 ;
    struct sockaddr_in server , client;
    struct sockaddr_in6 server6, client_addr;
    char client_message[2000];

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);
    
    
      //Create socket ipv6
    socket_desc6 = socket(AF_INET6 , SOCK_STREAM , 0);
    if (socket_desc6 == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server6.sin6_family = AF_INET6;
    server6.sin6_addr = in6addr_any;
    server6.sin6_port = htons(8888);

    //Bind 6
    if( bind(socket_desc6,(struct sockaddr *)&server6 , sizeof(server6)) < 0)
    {
        //print the error message
        perror("bind IPV6 failed. Error");
        return 1;
    }
    puts("bind IP V6done");

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

但结果是:

Socket created

bind done

Socket created

bind IPV6 failed. Error: Address already in use

是否可以使两个套接字ipv4/ipv6在同一个端口

技术上,你可以试试

setsockopt(socket_desc, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int))

setsockopt(socket_desc6, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int))

bind() 的相应调用之前,当然要进行适当的 return 值检查。

虽然这可能会有所帮助,但您应该查看以上评论,这可能会提供一个全新的视角。