Search code examples
csocketsipv6

create socket for both ipv6 and ipv4 with the same port


I would like to create a socket for both ipv4 and ipv6 with the same port. I use the fllowing C code for that :

#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;
}

but the result is:

Socket created

bind done

Socket created

bind IPV6 failed. Error: Address already in use

is it possible to make both socket ipv4/ipv6 at the same port


Solution

  • Technically, you can try

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

    and

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

    before the corresponding invocations of bind(), with appropriate return value checks, of course.

    Although this may turn out helpful, you should probably check out the above comments, which might offer a fresh perspective.