重新打开连接的数据报套接字
我有一个由客户定义的连接协议。使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许您可以尝试:
我还建议您仔细检查是否没有将相同的套接字传递给两个连续的 doConnect() 调用(如 errno 22 = EINVAL,其中 在bind()的情况下似乎意味着套接字已经绑定到一个地址)。
Perhaps you could try:
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).
底层套接字层可能保存端口和端口。即使在调用
close
之后,IP 地址仍然打开。尝试以下一些操作:close
和调用doConnect
之间执行sleep(10)
(或更多),再次setsockopt
将SO_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:sleep(10)
(or more) between theclose
and the call todoConnect
againsetsockopt
with theSO_LINGER
set to offThis actually happens more commonly with TCP connections, but I see no reason UDP can't have this problem as well.