简体   繁体   English

接收UDP数据包问题

[英]Issue receiving UDP packets

I'm trying to read the content of UDP packets sent by a hardware device connected locally to the laptop. 我正在尝试读取由本地连接到笔记本电脑的硬件设备发送的UDP数据包的内容。

In visual studio I wrote a quick w32 console application just to read an UDP packet of data: 在Visual Studio中,我编写了一个快速的w32控制台应用程序,仅用于读取UDP数据包:

WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) 
{
    MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
    exit(1);
}
SOCKADDR_IN addr; 
int sizeofaddr = sizeof(addr); 
addr.sin_addr.s_addr = inet_addr("192.168.1.1");
addr.sin_port = htons(1234); 
addr.sin_family = AF_INET; 

SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
listen(sListen, SOMAXCONN); //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections

SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
{
    MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
    return 0; //Failed to Connect
}
std::cout << "Connected!" << std::endl;

char MOTD[1280];
recvfrom(Connection, MOTD, sizeof(MOTD), 217, (SOCKADDR *)&addr, &sizeofaddr);
std::cout << "Done:" << MOTD << std::endl;

while (true)
{
    Sleep(10);
}

The output is: 输出为:

在此处输入图片说明 If I'm unplugging the device from the laptop I'm still having same result. 如果我从笔记本电脑上拔出设备的电源,我仍然会得到相同的结果。

I can see the UDP packets with the data in wireshark and all seems alright from that side. 我可以在Wireshark中看到带有数据的UDP数据包,从那边看来一切都还不错。

Any ideas what I'm doing wrong? 有什么想法我做错了吗? is it any other way to just receive UDP packets coming from the network? 还有什么其他方法可以只接收来自网络的UDP数据包?

Issue receiving UDP packets 接收UDP数据包问题

There is no code that receives UDP packets here. 这里没有代码可以接收UDP数据包。

I'm trying to read the content of UDP packets sent by a hardware device connected locally to the laptop. 我正在尝试读取由本地连接到笔记本电脑的硬件设备发送的UDP数据包的内容。

In visual studio I wrote a quick w32 console application just to read an UDP packet of data: 在Visual Studio中,我编写了一个快速的w32控制台应用程序,仅用于读取UDP数据包:

No you didn't. 不,你没有。

SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections

This line of code creates a TCP socket. 这行代码创建一个TCP套接字。 It needs an error check. 它需要一个错误检查。

bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket

This line of code needs an error check. 这行代码需要进行错误检查。

listen(sListen, SOMAXCONN); //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections

This line of code puts your TCP socket into LISTENING state. 这行代码使您的TCP套接字进入LISTENING状态。 It needs an error check. 它需要一个错误检查。

SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket

This line of code creates another TCP socket. 这行代码创建另一个TCP套接字。 It needs an error check. 它需要一个错误检查。

if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...

This line of code connects your second TCP socket to your first TCP socket's IP address and port. 这行代码将您的第二个TCP套接字连接到第一个TCP套接字的IP地址和端口。

Nothing so far has anything to do with UDP whatsoever. 到目前为止,与UDP无关。

recvfrom(Connection, MOTD, sizeof(MOTD), 217, (SOCKADDR *)&addr, &sizeofaddr);

This line of code receives from your second, connected, TCP socket. 这行代码从您的第二个连接的TCP套接字接收。 It needs an error check: it also needs its return value checked for zero, and otherwise this value should be used as the length of the data received. 它需要进行错误检查:还需要将其返回值检查为零,否则应将该值用作接收到的数据的长度。 However as you have never accepted this connection, let alone sent anything to the accepted socket, this line of code should block forever and never return. 但是,由于您从未接受过此连接,更不用说将任何内容发送到接受的套接字了,所以这一行代码将永远阻塞并且永远不会返回。

while (true)
{
    Sleep(10);
}

Sleeps in networking code are literally a waste of time. 网络代码中的睡眠实际上是在浪费时间。

The output is: 输出为:

The output is mere garbage, because you ignored the error code from recvfrom() , probably due to the flags value of 217 which you appear to have just made up. 输出只是垃圾,因为您忽略了来自recvfrom()的错误代码,可能是由于您似乎刚刚组成的flags值217所致。 If you're using real MSG_* values you should certainly use their names. 如果您使用的是真实的MSG_*值,则一定要使用其名称。 There are five bits set in 217, and even a TCP recv() only has three valid flags in Winsock. 在217中设置了五位,甚至TCP recv()在Winsock中也只有三个有效标志。

I can see the UDP packets with the data in wireshark and all seems alright from that side. 我可以在Wireshark中看到带有数据的UDP数据包,从那边看来一切都还不错。

There is nothing here that has anything to do with UDP packets. 这里与UDP数据包没有任何关系。 Any UDP packets you may have observed are coming from somewhere else and cannot possibly be received or sent by any of this code. 您可能观察到的所有UDP数据包都来自其他地方,并且任何此代码都可能无法接收或发送。

Any ideas what I'm doing wrong? 有什么想法我做错了吗?

Everything after WSAStartup() . WSAStartup()之后的所有内容。

is it any other way to just receive UDP packets coming from the network? 还有什么其他方法可以只接收来自网络的UDP数据包?

Yes. 是。 Use SOCK_DGRAM instead of SOCK_STREAM ; 使用SOCK_DGRAM代替SOCK_STREAM ; don't call listen() , don't create two sockets, don't call connect() . 不要调用listen() ,不要创建两个套接字,不要调用connect()

According to MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx , the receive function can use an ored combination of only 2 values: MSG_PEEK, MSG_OOB. 根据MSDN https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms740120(v=vs.85).aspx ,接收函数只能使用两个值的有序组合:MSG_PEEK,MSG_OOB 。

217 is more than just those two flags orded together. 217不仅仅是两个标志并列在一起。

You also should really be checking the return of function and on error could use WSAGetLastError to see what the issue is caused by. 您还应该真正检查函数的返回,并且在出错时可以使用WSAGetLastError来查看引起问题的原因。

You should also be using SOCK_DGRAM socket type when calling socket() to create a USB socket and UDP is connectionless - currently you are using TCP, and connecting to another TCP socket (the listen socket in your test program) 调用socket()创建USB套接字且UDP无连接时,还应该使用SOCK_DGRAM套接字类型-当前您正在使用TCP,并连接到另一个TCP套接字(测试程序中的监听套接字)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM