发出接收UDP数据包

时间:2017-06-28 11:45:40

标签: c++ sockets udp wireshark

我正在尝试读取本地连接到笔记本电脑的硬件设备发送的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);
}

输出结果为:

enter image description here 如果我从笔记本电脑上拔下设备,我仍然会有相同的结果。

我可以看到带有wireshark数据的UDP数据包,从那一方看来一切正常。

任何想法我做错了什么?是否只是接收来自网络的UDP数据包?

2 个答案:

答案 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套接字(测试程序中的侦听套接字)