C++ UDP recvfrom WSAGetLastError 10014

问题描述:

这可能是一个重复的问题,但我已阅读其他线程和解决方案,并发现代码中没有遗漏。有些东西是我无法弄清楚的。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初始化长度。仍然收到错误。不知道缺少什么。

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