Reputation: 1635
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
Reputation: 595329
The documentation for recvfrom()
is very clear on what causes 10014 (WSAEFAULT):
WSAEFAULT
The buffer pointed to by thebuf
orfrom
parameters are not in the user address space, or thefromlen
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