user3275095
user3275095

Reputation: 1635

C++ UDP recvfrom WSAGetLastError 10014

This may be a duplicate question but I have read the other threads and solutions and found nothing missing in the code. Something is there which I am not able to figure out.

Below is the code for a UDP server

#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 I am getting the WSAError 10014: The system detected an invalid pointer address in attempting to use a pointer argument of a call.

I tried setting the last two parameters to NULL, it works fine then, which means error is in those two pointer variables. But I have properly casted the sockaddr_in to sockaddr and also initialized the length with the sizeof sockaddr. Still getting the error. Don't know what is missing.

Upvotes: 5

Views: 7164

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595329

The documentation for recvfrom() is very clear on what causes 10014 (WSAEFAULT):

WSAEFAULT
The buffer pointed to by the buf or from parameters are not in the user address space, or the fromlen parameter is too small to accommodate the source address of the peer address.

You are assigning a string literal to the buffer that you pass to recvfrom():

buffer="WSAStartup was suuccessful\n";

A string literal resides in read-only memory that recvfrom() cannot write to.

Also, buffer is declared as char*, so using sizeof(buffer) is wrong.

You need to allocate writable memory for buffer, and get rid of the useless assignment, eg:

char buffer[65535];

Then sizeof(buffer) will be meaningful.

Upvotes: 7

Related Questions