重新打开连接的数据报套接字

时间:2010-09-22 16:11:27

标签: c++ linux udp connect

我有一个由我们的客户定义的连接协议。使用UDP和TCP协议在两台Linux计算机之间发送数据。 IP地址和端口在启动时是固定的。

我们正在以200 Hz的频率发送消息,而且我一直在使用connect来节省传输时间。

我的问题是,如果出现通信错误,我需要拆除连接并重新初始化。

我遇到其中一个UDP连接有问题,因为它不会重新绑定到所需的地址并返回错误22。

我使用的代码类似于:

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

使用它的方式是这样的:

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");  

发生错误时

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");

这里本地地址是172.17.21.3,我连接到172.17.21.1。 s1收听广播消息。

s1成功重新连接到远程计算机,但s2因调用bind而失败并显示错误22。

我已经尝试在关闭套接字之前立即调用bind并连接到AF_UNSPEC地址。这并没有解决问题。

我应该使用哪些选项?

2 个答案:

答案 0 :(得分:2)

也许你可以试试:

 int val = 1;
 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

我还建议你仔细检查一下,你没有将相同的套接字传递给两个连续的doConnect()调用(因为错误22 = EINVAL,in the case of bind()似乎意味着套接字已经绑定到一个地址。)

答案 1 :(得分:0)

底层套接字层可能包含端口&即使您致电close,IP地址仍然处于打开状态。尝试以下一些方法:

  • sleep(10)和再次呼叫close之间执行doConnect(或更多)
  • 使用setsockopt配置套接字并将SO_LINGER设置为关闭

这实际上更常见于TCP连接,但我认为UDP也没有理由不能解决这个问题。