0

我的程序接收到一些 UDP 消息,每个消息都是由客户端通过鼠标单击发送的。该程序具有仅用于设置一些参数的主线程(GUI)和创建第二个线程,具有

CreateThread(NULL, 0, MyFunc, &Data, 0, &ThreadTd);

即监听 UDP 数据包。这是 MyFunc:

... 
sd=socket(AF_INET, SOCK_DGRAM, 0);
if(bind(sd,(struct sockaddr *)&server,sizeof(struct sockaddr_in))==-1)
  ....
while(true){
bytes_received=recvfrom(sd,buffer,BUFFER_SIZE,0,(struct sockaddr *)&client,&client_length);
//parsing of the buffer
}

为了证明没有丢包,如果我使用了一个简单的脚本来侦听客户端使用某个端口发送的 UDP 消息,则发送的所有数据包都被我的计算机接收。当我运行我的应用程序时,只要客户端第一次单击鼠标,就会收到 UDP 消息,但是如果我尝试发送其他消息(其他鼠标单击),服务器不会收到它们(就像他没有t 捕获它们)和客户端,用户必须在服务器捕获消息之前至少单击 2 次。主线程并不一直忙,第二个线程只解析传入的消息,增强了一些变量,我没有为线程分配任何优先级。

有什么建议吗?

4

4 回答 4

2

除了 mark 的建议,您还可以使用 wireshark/netcat 查看数据报的发送时间/地点

于 2012-09-19T15:47:39.463 回答
0

没有足够的信息知道为什么会出现丢包。在到达第一个 recvfrom 之前,接收线程是否可能存在延迟?调试跟踪可能会指明方向。我还假设 struct sockaddr 服务器在调用 bind() 之前填充了一些理智的东西?你没有展示那部分......

于 2012-09-19T15:40:45.057 回答
0

这可能是与套接字编程有关的问题。我建议将调用select()epoll()与调用合并到recvfrom(). 这是一种更标准的套接字编程方法。这样,UDP 服务器可以接收来自多个客户端的消息,并且不会无限期地阻塞。

此外,如果问题是客户端并不总是为每次点击发送一个数据包,或者服务器不总是以某种方式接收它们,您应该隔离。Wireshark 可以帮助查看何时发送数据包。

于 2012-09-19T15:01:20.383 回答
0

如果我正确理解了您的问题,您的线程服务器应用程序在快速突发发送时不会收到所有数据包。您可以尝试的一件事是增加服务器端的套接字接收缓冲区,这样当您的应用程序读取速度不够快时,可以将更多数据排队。看setsockopt,使用SO_RCVBUF选项。

于 2012-09-19T19:02:46.517 回答