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

发布于 2024-09-24 15:55:31 字数 1719 浏览 3 评论 0原文

我有一个由客户定义的连接协议。使用 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 因调用绑定而失败并出现错误 22。

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

戒ㄋ 2024-10-01 15:55:31

也许您可以尝试:

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

我还建议您仔细检查是否没有将相同的套接字传递给两个连续的 doConnect() 调用(如 errno 22 = EINVAL,其中 在bind()的情况下似乎意味着套接字已经绑定到一个地址)。

Perhaps you could try:

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

I also suggest you double check that you're not passing the same socket to the two consecutive doConnect() calls (as errno 22 = EINVAL, which in the case of bind() appears to mean that the socket is already bound to an address).

檐上三寸雪 2024-10-01 15:55:31

底层套接字层可能保存端口和端口。即使在调用 close 之后,IP 地址仍然打开。尝试以下一些操作:

  • close 和调用 doConnect 之间执行 sleep(10) (或更多),再次
  • 使用以下命令配置套接字setsockoptSO_LINGER 设置为 off

这实际上在 TCP 连接中更常见,但我认为 UDP 没有理由不会出现此问题。

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

  • do a sleep(10) (or more) between the close and the call to doConnect again
  • configure the sockets using setsockopt with the SO_LINGER set to off

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文