2017-06-28 124 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