2014-10-17 333 views
0

這可能是一個重複的問題,但我已閱讀其他線程和解決方案,並發現代碼中沒有遺漏。有些東西是我無法弄清楚的。C++ UDP recvfrom WSAGetLastError 10014

下面是一個UDP服務器

#pragma once 
#pragma comment(linker, "/defaultlib:ws2_32.lib") 

#include <io.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <process.h> 
#include <winsock.h> 
#include <iostream> 
#include <windows.h> 
#include <string> 
#include <stdio.h> 
using namespace std; 
#define REQUEST_PORT 0x7070 
#define TIMEOUT_USEC 300000   
#define MAX_RETRIES 3   
int port=REQUEST_PORT; 
//socket data types 
SOCKET serverSocket; 
SOCKET cs; 
SOCKADDR_IN serverSocketAddr; 
SOCKADDR_IN clientSocketAddr; 
int senderAddrSize = sizeof (clientSocketAddr); 
char *buffer; 
char localhost[21]; 
HOSTENT *hp; 

int main(void) 
{ 
    try 
    { 
     initializeSockets(); 
    } 
    catch(char* str) 
    { 
     LPTSTR Error = 0; 
     if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,WSAGetLastError() | GetLastError(),0,(LPTSTR)&Error,0,NULL) == 0) 
     { 
      cout<<str<<endl; 
     } 
     else 
     { 
      cerr<<Error<<endl; 
     } 
     LocalFree(Error); 
    } 
    return 0; 
} 
void initializeSockets() 
{ 
    try 
    { 
     WSADATA wsadata; 
     if (WSAStartup(0x0202,&wsadata)!=0) 
     { 
      throw "Error in starting WSAStartup()"; 
     } 
     else 
     { 
      buffer="WSAStartup was suuccessful\n"; 
     } 
     gethostname(localhost,20); 
     cout<<"hostname: "<<localhost<< endl; 
     if((hp=gethostbyname(localhost)) == NULL) 
     { 
      cout << "Cannot get local host info." 
       << WSAGetLastError() << endl; 
      exit(1); 
     } 
     if((serverSocket = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) 
      throw "can't initialize socket"; 
     serverSocketAddr.sin_family = AF_INET; 
     serverSocketAddr.sin_port = htons(port); 
     serverSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

     if (::bind(serverSocket,(LPSOCKADDR)&serverSocketAddr,sizeof(serverSocketAddr)) == SOCKET_ERROR) 
      throw "can't bind the socket"; 
     if(recvfrom(serverSocket,buffer,sizeof(buffer),0,(SOCKADDR *)&clientSocketAddr, &senderAddrSize)==SOCKET_ERROR) 
       throw "Error"; 

    } 
    catch(char* str) 
    { 
     LPTSTR Error = 0; 
     if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,WSAGetLastError() | GetLastError(),0,(LPTSTR)&Error,0,NULL) == 0) 
     { 
      cout<<str<<endl; 
     } 
     else 
     { 
      cerr<<Error<<endl; 
     } 
     LocalFree(Error); 
    } 
} 

上recvfrom的我收到WSAError 10014代碼:系統中嘗試使用呼叫指針參數檢測到無效的指針地址。

我試着將最後兩個參數設置爲NULL,它工作正常,這意味着錯誤在這兩個指針變量中。但是我已經正確地將sockaddr_in轉換爲sockaddr,並且使用sizeof sockaddr初始化長度。仍然收到錯誤。不知道缺少什麼。

回答

4

documentationrecvfrom()是什麼原因導致10014(WSAEFAULT)很明確:

WSAEFAULT
緩衝器由buffrom參數指向不在用戶地址空間,或fromlen參數太小,無法容納對等地址的源地址。在只讀存儲器recvfrom()不能寫

buffer="WSAStartup was suuccessful\n"; 

字符串文字所在:

要指定一個字串,你傳遞給recvfrom()buffer

另外,buffer被宣佈爲char*,所以使用sizeof(buffer)是錯誤的。

您需要分配可寫內存buffer,並且擺脫了無用的任務,例如:

char buffer[65535]; 

然後sizeof(buffer)將是有意義的。

+0

謝謝雷米。我想我只是忽略了WSAEFAULT的粗體部分,只關注結構長度部分。下次會更小心謹慎。 – user3275095 2014-10-17 13:01:22