我正在尝试读取本地连接到笔记本电脑的硬件设备发送的UDP数据包的内容。
在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);
}
输出结果为:
我可以看到带有wireshark数据的UDP数据包,从那一方看来一切正常。
任何想法我做错了什么?是否只是接收来自网络的UDP数据包?
答案 0 :(得分:1)
发出接收UDP数据包
这里没有接收UDP数据包的代码。
我正在尝试读取本地连接到笔记本电脑的硬件设备发送的UDP数据包的内容。
在visual studio中,我写了一个快速的w32控制台应用程序,只是为了读取UDP数据包:
不,你没有。
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
这行代码创建了一个TCP套接字。它需要进行错误检查。
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
这行代码将您的TCP套接字置于LISTENING状态。它需要进行错误检查。
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL); //Set Connection socket
这行代码创建了另一个TCP套接字。它需要进行错误检查。
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
这行代码将第二个TCP套接字连接到第一个TCP套接字的IP地址和端口。
到目前为止,没有任何东西与UDP有任何关系。
recvfrom(Connection, MOTD, sizeof(MOTD), 217, (SOCKADDR *)&addr, &sizeofaddr);
这行代码从第二个连接的TCP套接字接收。它需要进行错误检查:它还需要检查其返回值为零,否则该值应该用作接收数据的长度。但是,由于您从未接受过此连接,更不用说将任何内容发送到接受的套接字,这行代码应该永久阻止而永远不会返回。
while (true)
{
Sleep(10);
}
网络代码中的睡眠实际上是浪费时间。
输出结果为:
输出仅仅是垃圾,因为您忽略了recvfrom()
的错误代码,可能是由于您似乎刚刚编写的flags
值为217。如果您使用真正的MSG_*
值,您当然应该使用他们的名字。在217中设置了五个位,甚至TCP recv()
在Winsock中只有三个有效标志。
我可以看到带有wireshark数据的UDP数据包,从那一方看来一切正常。
这里没有任何与UDP数据包有关的内容。您可能观察到的任何UDP数据包都来自其他地方,并且不可能通过任何此代码接收或发送。
任何想法我做错了什么?
WSAStartup()
后的所有内容。
是否只是接收来自网络的UDP数据包的其他任何方式?
是。使用SOCK_DGRAM
代替SOCK_STREAM
;不要拨打listen()
,不要创建两个套接字,不要拨打connect()
。
答案 1 :(得分:0)
根据MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx,接收函数只能使用2个值的组合:MSG_PEEK,MSG_OOB。
217不仅仅是那两个标记在一起的旗帜。
你也应该检查函数的返回,并且在出错时可以使用WSAGetLastError来查看问题是由什么造成的。
在调用socket()创建USB套接字并且UDP是无连接时,您还应该使用SOCK_DGRAM套接字类型 - 当前您正在使用TCP,并连接到另一个TCP套接字(测试程序中的侦听套接字)