There is no problem with your Socket Programming.
What you need to look at, is the logic.
Here the Server and Client are two different process, having its own address space.
Your Socket programming is perfectly fine.
For Example:
Client Side :
send(sockfd, &test, sizeof(test), 0)
printf ("Value of test->e_recv = [%d]\n", test.e_recv);
printf ("Value of test->ptr = [%u]\n", test.ptr);
$ ./client 172.16.7.110 56000
Value of test->e_recv = [1]
Value of test->ptr = [3214048236] // Address of some variable in Client address space.
Data Sent!
Server will recieve exactly the same data.
Server Side:
NwInfo *pRecvNwInfo = malloc(sizeof(NwInfo));
int nbytes = recv(filedes, pRecvNwInfo, sizeof(NwInfo), 0);
printf("Value of pRecvNwInfo->e_recv = [%d]\n", pRecvNwInfo->e_recv);
printf("Value of pRecvNwInfo->ptr = [%u]\n", pRecvNwInfo->ptr);
$./server 56000
Here is the message.
Value of pRecvNwInfo->e_recv = [1]
Value of pRecvNwInfo->ptr = [3214048236] // Address received correctly, but it is of client address space
So when you write this:
pst = (struct student *)pRecvNwInfo->pvData;
pst
is pointing to the address, which is valid only in client address context.
So accessing it (in server's context) will give you Undefined Behavior, In my case SIGSEGV.
Important Note:
When you send
, you are sending the data in the address of test
and when you recv
it, you are receiving the data in some new container (pRecvNwInfo
) with a different address.
How to Rectify this:
Its best to send values and not the address.
Consider the following structure:
typedef struct inner
{
int a;
int b;
}inner_t;
typedef struct outer
{
void *ptr;
int c;
}outer_t;
You may change your Structure definition of outer
:
Change the void *
to actual data and not address, something like. inner_t var
.
send(sockfd, &test, sizeof(test), 0);
Create a temporary structure type (for Sending & Receiving).
/* Temporary Buffer Declaration */
typedef struct temp{
inner_t value_in;
outer_t value_out;
} temp_t;
temp_t to_send;
inner_t buffer_in;
/* Save values instead of address */
memcpy(buffer_in, ptr, sizeof(inner_t));
to_send.value_in = buffer;
to_send.value_out = outer;
/* Send the final structure */
send(sockfd, &to_send, sizeof(temp_t), 0);
These may not be the best practices, I would love to know if there are any better ones.