C ++ UDP recvfrom от WSAGetLastError 10014

0

Это может быть дублированный вопрос, но я прочитал другие темы и решения и не нашел ничего в коде. Что-то есть, чего я не могу понять.

Ниже приведен код для 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);
    }
}

on recvfrom Я получаю WSAError 10014: система обнаружила неверный адрес указателя при попытке использовать аргумент указателя вызова.

Я попытался установить последние два параметра в NULL, он отлично работает, что означает, что ошибка в этих двух переменных указателя. Но я правильно запустил sockaddr_in в sockaddr, а также инициализировал длину с размером sockaddr. Все еще получаю ошибку. Не знаю, чего не хватает.

Теги:
sockets
udp

1 ответ

4
Лучший ответ

В документации для recvfrom() очень ясно, что вызывает 10014 (WSAEFAULT):

WSAEFAULT
Буфер, на который указывает buf или from параметров, не находится в адресном пространстве пользователя, или параметр fromlen слишком мал для размещения адреса источника адреса однорангового узла.

Вы назначаете строковый литерал в buffer который вы передаете recvfrom():

buffer="WSAStartup was suuccessful\n";

Строковый литерал находится в постоянной памяти, которую recvfrom() не может записать.

Кроме того, buffer объявляется как char*, поэтому использование sizeof(buffer) неверно.

Вам необходимо выделить записываемую память для buffer и избавиться от бесполезного назначения, например:

char buffer[65535];

Тогда sizeof(buffer) будет иметь смысл.

  • 0
    Спасибо, Реми. Я думаю, что я просто проигнорировал часть, выделенную жирным шрифтом WSAEFAULT, и сосредоточился только на части длины структуры. Будет более осторожным и наблюдательным в следующий раз.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню