c++linuxudp

Reopen connected datagram socket


I have a connection protocol that has been defined by our customer. Data are sent between two linux computers using UDP and TCP protocols. The IP addresses and ports are fixed on startup.

We are sending messages at 200 Hz and I have been using connect to save some time on the transmissions.

My problem is that if there is a communication error, I need to tear down the connections and reinitialise.

I have a problem with one of the UDP connections as it will not rebind to the required address and returns errno 22.

The code I am using is something like:

int  
doConnect(int& sock, int local_port, char *local_ip, int remote_port, char *remote_ip)  
{  
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);  
    struct sockaddr_in addr;  

    memset(&addr, 0, sizeof(sockaddr_in);  
    addr.sin_family = AF_INET;  
    addr.sin_port = htons(local_port);  
    inet_pton(local_ip,&addr.sin_addr.s_addr); 

    if (0 > bind(sock, (struct sockaddr*)&addr, sizeof(addr)))  
    {
        printf("Bind Error errno = %d\n", errno);
        return ERR_BIND;  
    }

    memset(&addr, 0, sizeof(sockaddr_in);  
    addr.sin_family = AF_INET;  
    addr.sin_port = htons(remote_port);  
    inet_pton(remote_ip,&addr.sin_addr.s_addr); 

    if (0 > connect(sock, (struct sockaddr*)&addr, sizeof(addr)))  
    {
        printf("Connect Error errno = %d\n", errno);
        return ERR_CONNECT;  
    }
    return ERR_OK;
}

The way that this is used is like this:

int s1(-1), s2(-1);  
doConnect(s1, 31003, "172.17.21.255", 31006, "172.17.21.1");  
doConnect(s2, 31001, "172.17.21.3", 31004, "172.17.21.1");  

When an error occurs

close(s1);
close(s2);

doConnect(s1, 31003, "172.17.21.255", 31006, "172.17.21.1");
doConnect(s2, 31001, "172.17.21.3", 31004, "172.17.21.1");

Here the local address is 172.17.21.3 and I am connecting to 172.17.21.1. s1 listens to a broadcast message.

s1 successfully reconnects to the remote machine, but s2 fails with error 22 from the call to bind.

I have tried explicitly calling bind and connect to an AF_UNSPEC address immediately before I close the socket. This doesn't solve the problem.

Are there any options that I should be using?


Solution

  • The underlying socket layer might hold the port & IP address still open, even after your call to close. Try some of the following:

    This actually happens more commonly with TCP connections, but I see no reason UDP can't have this problem as well.