我正在尝试通过TCP中的套接字发送结构。但是,当我收到结构中的数据时,我得到一个空结构。
这是客户发送的结构:
typedef struct NwInfo
{
void *pvData;
NwTypes e_recv;
}NwInfo;
struct NwInfo test;
test.e_recv = 1;
test.pvData = (void *) &pst; //pst is object of another structure.
int ret =send(sockfd,&test,sizeof(test),0); //ret returns greater than 0
在服务器端:
NwInfo *pRecvNwInfo;
pRecvNwInfo = malloc(sizeof(NwInfo));
int nbytes = recv(filedes,pRecvNwInfo,sizeof(NwInfo),0);
//nbytes is the same value as that of ret
struct student *pst;
pst = (struct student *)pRecvNwInfo->pvData;
服务器端的pst变量没有获取任何数据。谁能指出我正在犯的错误?
答案 0 :(得分:1)
您的套接字编程没有问题 你需要看的是逻辑。
这里的服务器和客户端是两个不同的进程,有自己的地址空间。
你的Socket编程非常好。 例如:
客户端:
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!
服务器将收到完全相同的数据 服务器端:
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
所以当你这样写:
pst = (struct student *)pRecvNwInfo->pvData;
pst
指向地址,仅在客户端地址上下文中 有效 。
因此,访问它(在服务器的上下文中)将为您提供Undefined Behavior,在我的情况下SIGSEGV。
重要提示:
当您send
时,您要发送test
地址的数据,当您recv
时,您正在使用某个新容器(pRecvNwInfo
)接收数据不同的地址。
如何纠正:
最好发送值而不是地址。
考虑以下结构:
typedef struct inner
{
int a;
int b;
}inner_t;
typedef struct outer
{
void *ptr;
int c;
}outer_t;
您可以更改outer
的结构定义:
将void *
更改为实际数据而不是地址,例如。 inner_t var
。
send(sockfd, &test, sizeof(test), 0);
创建临时结构类型(用于发送和接收)。
/* 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);
这些可能不是最佳做法,我很想知道是否有更好的做法。
答案 1 :(得分:0)
您需要使用memcpy复制test.pvData成员中的pst值。您只是将内存地址分配给test.pvData,其值在服务器端不可用。你可以这样做:
memcpy(test.pvData, &pst, sizeof pst);
编辑:您还必须为pvData提供一些内存空间,而不仅仅是指针。
答案 2 :(得分:0)
你不能在发送缓冲区时使用sizeof(test)
,因为sizeof(test)
将保留内存中结构的大小,因为你希望发送的数据仅由结构指向它< strong> NOT 包含在该大小中。
代替,
保持您要发送的数据的大小,并创建一个将该值保存在字段中的结构,并留出足够的空间将数据复制到该字段中。然后将所有数据memcpy到struct并将其作为一个整体发送。
无论如何,我建议您直接在想要发送的结构中填充数据如果可以这将保存memcpy。