When I run following code, I always get WSAEFAULT error. Not sure what am I doing wrong? Any help will be appreciated. Thank you.
uint8_t status = ICRON_OK;
struct sockaddr_in serverAddr, clientAddr;
int rc = 0;
int clen = sizeof(clientAddr);
int serverSocket;
if((serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
printf("Socket Creation failure\n");
exit(EXIT_FAILURE);
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(ICONTROLNET_EVENT_PORT);
if(bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
printf("bind failure\n");
WSACleanup();
closesocket(serverSocket);
exit(EXIT_FAILURE);
}
if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, (int *)sizeof(serverAddr)) != 0)
{
printf("GETSOCKNAME ERROR = %d\n", WSAGetLastError());
//Here always get WSAEFAULT
}
CodePudding user response:
According to the official Microsoft documentation for the function getsockname, when you get the error code WSAEFAULT
, it means the following:
The
name
or thenamelen
parameter is not a valid part of the user address space, or thenamelen
parameter is too small.
This documentation later states the following about the namelen
parameter, which is the third parameter of getsockname
:
On call, the
namelen
parameter contains the size of thename
buffer, in bytes. On return, thenamelen
parameter contains the actual size in bytes of thename
parameter.
When the documentation uses the word "contains", it means that the pointer namelen
should point to an int
which specifies the size of the object pointed to by name
(the second parameter).
You are passing the following expression as the third parameter:
(int *)sizeof(serverAddr)
This is wrong. It is correct to use the expression sizeof serverAddr
or sizeof(serverAddr)
. However, instead of casting that value to a pointer and passing that pointer directly to the function getsockname
, you should instead pass a pointer to an int
which contains the value sizeof serverAddr
.
Therefore, you should change the line
if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, (int *)sizeof(serverAddr)) != 0)
to:
int serverAddrSize = sizeof serverAddr;
if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, &serverAddrSize) != 0)