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初始化长度。仍然收到错误。不知道缺少什么。
答
的documentation为recvfrom()
是什么原因导致10014(WSAEFAULT)很明确:
WSAEFAULT
缓冲器由buf
或from
参数指向不在用户地址空间,或fromlen
参数太小,无法容纳对等地址的源地址。在只读存储器recvfrom()
不能写buffer="WSAStartup was suuccessful\n";
字符串文字所在:
要指定一个字串,你传递给recvfrom()
的buffer
。
另外,buffer
被宣布为char*
,所以使用sizeof(buffer)
是错误的。
您需要分配可写内存buffer
,并且摆脱了无用的任务,例如:
char buffer[65535];
然后sizeof(buffer)
将是有意义的。
谢谢雷米。我想我只是忽略了WSAEFAULT的粗体部分,只关注结构长度部分。下次会更小心谨慎。 – user3275095 2014-10-17 13:01:22