2017-06-28 129 views
0

我试图读取本地连接到笔记本电脑的硬件设备发送的UDP数据包的内容。接收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数据包?

+1

你可以使用符号的标志请'217'是什么标志? –

+1

你没有检查'recvfrom'的值。 – Mat

+0

嗨理查德,对不起,我发布了错误的函数,实际上我得到了:recvfrom(连接,MOTD,sizeof(MOTD),0,(SOCKADDR *)&addr,&sizeofaddr);国旗是0 – joe

回答

0

根据MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx,接收函数可以使用仅有的两个值的组合:MSG_PEEK,MSG_OOB。

217不仅仅是这两个旗帜结合在一起。

你也应该真的在检查函数的返回值,错误时可以使用WSAGetLastError来查看问题是由什么引起的。

打电话时插座()来创建一个USB插口和UDP是无连接的,您也应该使用SOCK_DGRAM套接字类型 - 您当前正在使用TCP,并连接到另一个TCP套接字(侦听套接字在您的测试程序)

0

问题收到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()忽略该错误代码,可能是由于你似乎刚才提出了217 flags值。如果你使用真正的MSG_*值,你应该使用他们的名字。在217中设置了5个位,甚至TCP recv()在Winsock中只有三个有效标志。

我可以在wireshark中看到带有数据的UDP数据包,从所有方面来看似乎都没问题。

这里没有什么与UDP数据包有关的东西。您可能观察到的任何UDP数据包都来自其他地方,并且不可能通过任何此代码进行接收或发送。

任何想法我做错了什么?

WSAStartup()之后的所有内容。

是否有任何其他方式来接收来自网络的UDP数据包?

是的。使用SOCK_DGRAM而不是SOCK_STREAM;不要拨打listen(),不要创建两个套接字,不要拨打connect()

+0

感谢您的回答,我会尝试你的建议。 – joe

+0

你应该先看一下UDP教程。你写的代码完全没有意义。 – EJP