【发布时间】:2018-02-27 20:34:05
【问题描述】:
我有一个简单的 udp 客户端/服务器程序。
如果客户端失去连接,或者服务器正在重新启动,客户端将不会自动重新连接。我总是必须手动重启客户端。
这是我的客户端套接字配置:
struct sockaddr_in si_other;
int s, i, j, slen=sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN] = "0";
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
die("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
这是我无限循环的主要部分:
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1)
die("sendto()");
//clear buf
memset(buf,'\0', BUFLEN);
//try to receive some data, this is a blocking call
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1)
die("recvfrom()");
在做了一些研究后,我尝试通过添加以下行将套接字模式更改为非阻塞:
fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0 | O_NONBLOCK);
客户端现在可以向服务器发送一条消息,但客户端没有收到任何答复。错误信息是:
recvfrom():资源暂时不可用
【问题讨论】:
-
UDP 套接字根本不建立连接
-
与
EGAIN错误有关吗?recvfrom()操作会阻塞,但由于套接字是非阻塞,它会立即返回。 -
@bukkojot 是的,抱歉措辞不好。客户端正在无限循环中发送消息。我的目标是当服务器几秒钟不可用时,客户端应该继续发送消息。
-
您确定您的服务器已成功重新绑定到套接字吗?如果服务器在没有正确释放套接字的情况下重新启动,它将在一段时间内不可用,除非您强制绑定 (SO_REUSEADDR)。正如您所期望的那样,客户端应该是垃圾邮件转储机器,发送 UDP 数据包,因此问题可能出在您的服务器上...
-
@HansPetterTaugbølKragset 服务器未显示“地址已在使用”之类的内容。也许这是一个有用的提示:想象一下我想在服务器之前启动客户端。这也不起作用。