【问题标题】:C++ UDP recvfrom WSAGetLastError 10014C++ UDP recv来自 WSAGetLastError 10014
【发布时间】:2014-12-12 15:06:34
【问题描述】:

这可能是一个重复的问题,但我已经阅读了其他线程和解决方案,发现代码中没有任何遗漏。有一些我无法弄清楚的东西。

下面是 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 初始化了长度。仍然收到错误。不知道缺少什么。

【问题讨论】:

    标签: c++ c sockets udp


    【解决方案1】:

    recvfrom()documentation 非常清楚导致 10014 (WSAEFAULT) 的原因:

    WSAEFAULT
    buffrom参数指向的缓冲区不在用户地址空间中,或者fromlen参数太小,无法容纳源地址对等地址。

    您正在为您传递给recvfrom()buffer 分配一个字符串文字:

    buffer="WSAStartup was suuccessful\n";
    

    字符串文字驻留在recvfrom() 无法写入的只读内存中。

    另外,buffer 被声明为char*,所以使用sizeof(buffer) 是错误的。

    你需要为buffer分配可写内存,并去掉无用的赋值,例如:

    char buffer[65535];
    

    那么sizeof(buffer)就有意义了。

    【讨论】:

    • 谢谢雷米。我想我只是忽略了 WSAEFAULT 的粗体部分,只关注结构长度部分。下次会更加细心和细心。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2014-10-15
    • 2021-01-21
    • 2011-05-19
    • 2015-06-18
    • 2010-11-26
    相关资源
    最近更新 更多