【问题标题】:Reopen connected datagram socket重新打开连接的数据报套接字
【发布时间】:2010-09-23 01:00:57
【问题描述】:

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

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

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

我的 UDP 连接之一有问题,因为它不会重新绑定到所需的地址并返回 errno 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。

我尝试在关闭套接字之前立即显式调用绑定并连接到 AF_UNSPEC 地址。这并不能解决问题。

有什么我应该使用的选项吗?

【问题讨论】:

  • 我注意到每次调用 doConnect 时都会在 s1 和 s2 中设置相同的套接字 id。 s1 和 s2 不是同一个值。

标签: c++ linux udp connect


【解决方案1】:

也许你可以试试:

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

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

【讨论】:

    【解决方案2】:

    即使在您调用close 之后,底层套接字层也可能保持端口和IP 地址仍然打开。尝试以下方法:

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

    这实际上更常发生在 TCP 连接中,但我认为 UDP 没有理由也不会有这个问题。

    【讨论】:

      猜你喜欢
      • 2010-10-29
      • 2015-04-13
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多