通过套接字发送后C结构没有填充值

时间:2014-11-03 07:20:18

标签: c sockets pointers

我正在尝试通过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变量没有获取任何数据。谁能指出我正在犯的错误?

3 个答案:

答案 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;        
  1. 您可以更改outer的结构定义: 将void *更改为实际数据而不是地址,例如。 inner_t var

    send(sockfd, &test, sizeof(test), 0);
    
  2. 创建临时结构类型(用于发送和接收)。

    /* 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);
    
  3. 这些可能不是最佳做法,我很想知道是否有更好的做法。

答案 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。