2014-09-30 497 views
-5
//UDP receiver 
int main() 
{ 
    WSAData wsaData; 
    SOCKET receivingSocket; 
    SOCKADDR_IN receiverAddr; 
    SOCKADDR_IN senderAddr; 
    int senderAddrSize = sizeof(senderAddr); 
    int port=51020; 
    char receiveBuf[1024]; 
    int bufLength=1024; 

    cout << "UDP receiver\n"; 

    //Initialize winsock 
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0) 
    { 
     cout << "Failed. Error Code : " << WSAGetLastError(); 
     exit(EXIT_FAILURE); 
    } 
    cout << "Initialised\n";` 

    if(receivingSocket = socket(AF_INET, SOCK_DGRAM, 0) == INVALID_SOCKET) 
    { 
     cout << "Could not create socket :" << WSAGetLastError(); 
    } 
    cout << "Socket created.\n"; 

    //fill up SOCKADDR_IN structure 
    senderAddr.sin_port = htons(port); 
    senderAddr.sin_family = AF_INET; 
    senderAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    //Bind information with socket 
    bind(receivingSocket, (SOCKADDR*)&senderAddr, sizeof(senderAddr)); 

    while(1) 
    { 
     cout << "Waiting for message\n"; 

     //try to receive some data, this is a blocking call 
     if (recvfrom(receivingSocket, receiveBuf, 1024, 0, (SOCKADDR*)&senderAddr, &senderAddrSize)) == SOCKET_ERROR)) 
     { 
      cout << "recvfrom() failed with error code :" << WSAGetLastError(); 
      exit(EXIT_FAILURE); 
     } 
     cout << receiveBuf; 
    } 

    //Close socket 
    closesocket(receivingSocket); 
    WSACleanup(); 
    std::cin.get(); 
    return 0; 
} 

C++ socket編程:SENDTO()和recvfrom()錯誤代碼10038&在 '服務器' 綁定失敗與10038

//UDP server 
int main() 
{ 
    WSAData wsaData; 
    SOCKET sendingSocket; 
    SOCKADDR_IN receiverAddr; 
    int port = 51010; 
    char sendBuf[1024]="Hello!!!"; 
    int bufLength = 1024; 

    cout << "UDP server from book\n"; 

    //Initialize socket 
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0) 
    { 
     cout << "Failed. Error Code : " << WSAGetLastError(); 
     exit(EXIT_FAILURE); 
    } 
    cout << "Initialised\n"; 

    if(sendingSocket = socket(AF_INET, SOCK_DGRAM, 0) == INVALID_SOCKET) 
    { 
     cout << "Could not create socket : " << WSAGetLastError(); 
    } 
    cout << "Socket created.\n"; 

    //FIll out structure of receiverAdd 
    receiverAddr.sin_family = AF_INET; 
    receiverAddr.sin_port = htons(port); 
    receiverAddr.sin_addr.s_addr = inet_addr("192.168.1.100"); 

    int test = bind(sendingSocket, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr)); 
    if(test < 0) 
    { 
     cout << "Bind failed with error code : %d" << WSAGetLastError(); 
     exit(EXIT_FAILURE); 
    } 
    cout << "Bind is successful\n"; 

    while(1) 
    { 
     cout << "Sending data...\n"; 

     //Send datagram to receiver 
     if(sendto(sendingSocket, sendBuf, 1024, 0, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr)) == SOCKET_ERROR) 
     { 
      cout << "sendto() failed with error code : " << WSAGetLastError(); 
      exit(EXIT_FAILURE); 
     } 
     cout << "Sent"; 
    } 

    //close socket 
    closesocket(sendingSocket); 

    WSACleanup(); 

    std::cin.get(); 

    // return 0; 
} 
+5

你忘了提問了。 – 2014-09-30 21:11:39

+0

此代碼是可以格式化的。我爲您解決了這個問題,但下次請在發佈代碼片段時[學習如何正確格式化](http://stackoverflow.com/help/formatting)代碼片段。 – 2014-09-30 21:15:51

+1

您還忘了查看Winsock錯誤10038. – EJP 2014-09-30 21:25:16

回答

3

錯誤10038是WSAENOTSOCK: The descriptor is not a socket.

要調用socket()和分配您的SOCKET處理if語句的內部,但是您缺少足夠的括號。他們應該是這樣的,而不是:

if((receivingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) 

if((sendingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) 

就個人而言,我討厭執行的if語句像這裏面的分配代碼。我寧願將它們分開。它是清潔,容易出錯少,沒有效率較低,從編譯器的角度來看:

receivingSocket = socket(AF_INET, SOCK_DGRAM, 0); 
if(receivingSocket == INVALID_SOCKET) 

sendingSocket = socket(AF_INET, SOCK_DGRAM, 0); 
if(sendingSocket == INVALID_SOCKET) 

在一個側面說明:

  1. WSAStartup()不適合使用WSAGetLastError()錯誤報告,它直接返回錯誤代碼。這在WSAStartup()文檔中有明確說明。進入recvfrom()循環之前

    int err = WSAStartup(MAKEWORD(2,2),&wsaData); 
    if (err != 0) 
    { 
        cout << "Failed. Error Code : " << err; 
        exit(EXIT_FAILURE); 
    } 
    
  2. 您的UDP接收器不檢查的bind()一個錯誤的返回值。

+1

此外,當表達式,條件等等分散在多個具有中間變量的行(和優化關閉)時,調試更容易。將複雜表達式集成到一行意味着在單步執行源代碼時可能會錯過或誤解錯誤。 – 2014-09-30 21:53:09

+0

10047是'WSAEAFNOSUPPORT'。如果你沒有正確地初始化'sin_family',你可以用'bind()'來得到這個錯誤的唯一方法。這與您選擇綁定的IP無關。當接收到數據包時,你可以綁定到'INADDR_ANY',但是當發送數據包時,你不能綁定到'INADDR_ANY'。出站數據包必須具有從其發送的特定IP。 – 2014-10-01 17:43:07

+0

傳遞給'bind()'的'sockaddr'代表recvfrom()'監聽的'LOCAL *地址和'sendto()'發送的地址。傳遞給sendto()和recvfrom()的'sockaddr'表示* REMOTE *地址,發送給sendto()的地址和從'recvfrom()'發送的地址。調用'bind()'時,你的命名規則有點倒退,你應該使用單獨的'sockaddr'變量進行綁定和發送/接收。 – 2014-10-01 17:45:19