[英]Trying to receive incoming UDP packets, empty buffer
我正在尝试使用Wireshark读取这些传入的UDP数据包:
我正在使用下一个代码:
struct sockaddr_in si_other;
struct sockaddr_in remaddr; /* remote address */
int slen = sizeof(remaddr);
int s, recvlen;
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) //IPPROTO_UDP
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
if (bind(s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0) {
perror("bind failed");
return 0;
}
u_long nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket(s, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return 0;
}
//start communication
while (1)
{
printf("waiting on port %d\n", PORT);
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Done");
puts(buf);
}
我绑定的地址是192.168.1.1和端口1234。
WSAGetLastError给定的输出是一个空的缓冲区错误:10035
我试图断开防火墙,防病毒软件的连接...并且我以管理员身份运行该程序,但无济于事。
为什么缓冲区为空? 我清楚地看到有数据包到来,这有什么可能阻止传入的数据到套接字?
WSAGetLastError()
给定的输出是一个空的缓冲区错误:10035
不,不是。 10035是WSAEWOULDBLOCK
。 这意味着该操作将在阻塞模式下阻塞,即在您调用recvfrom()
不存在要接收的数据。
我绑定的地址是192.168.1.1
IP 192.168.1.1显示为网关
这两个陈述是相互矛盾的。 如果是网关,则是外部IP地址;如果是外部IP地址,则无法绑定到该地址。
我尝试了INADDR_ANY,但没有帮助
不奇怪。 如果您不是192.168.1.1,则无法接收其消息。 不清楚为什么会这样认为。
正如@EJP所提到的10035是WSAEWOULDBLOCK
,即没有数据准备就绪。 原因是接收者是192.168.1.1,这是您网关的IP地址,因此不是本地IP。 在这种情况下,您将无法以正常方式接收数据包。
即使不适合您,也可以使用UDP嗅探器(例如,使用libpcap)来接收这些数据包。
感谢您的回答,他们为我指出了正确的方向。 现在,我的程序开始工作了,我能够接收传入的UDP数据包。
解决方案是“嗅探”这些UDP数据包,winsock允许在绑定后使用WSAIoctl函数,在我的情况下,将下一个代码添加到上述程序中(在bind函数之后):
if (WSAIoctl(s, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&si_other, 0, 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
return 1;
}
我希望可以帮助其他人解决类似的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.