C:通过TCP套接字发送嵌套结构

C:通过TCP套接字发送嵌套结构,c,sockets,struct,tcp,malloc,C,Sockets,Struct,Tcp,Malloc,虽然这可能是一篇重复的文章,但我想确定它在我的特定代码中是如何工作的 我想要实现什么? 通过TCP/IP连接发送和接收结构 到目前为止我有什么? 发送方 初始化结构: typedef struct soutputdata { unsigned long long ull_date; unsigned int ui_ixl; unsigned int ui_type; unsigned int ui_index; char c_values

虽然这可能是一篇重复的文章,但我想确定它在我的特定代码中是如何工作的

我想要实现什么?

通过TCP/IP连接发送和接收结构

到目前为止我有什么?

发送方

初始化结构:

typedef struct soutputdata {
    unsigned long long ull_date;
    unsigned int    ui_ixl;
    unsigned int    ui_type;
    unsigned int    ui_index;
    char c_values[64][2];
    int i_valueid;
} s_OUTPUTDATA;

typedef struct sheader {
    int i_head;
} s_HEADER;

typedef struct soutdata {
    s_HEADER *sHeader;
    s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
typedef struct soutputdata {
    unsigned long long ull_date;
    unsigned int    ui_ixl;
    unsigned int    ui_type;
    unsigned int    ui_index;
    char c_values[64][2];
    int i_valueid;
} s_OUTPUTDATA;

typedef struct sheader {
    int i_head;
} s_HEADER;

typedef struct soutdata {
    s_HEADER *sHeader;
    s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
现在我想向连接的TCP客户端发送一个s_OUTDATA结构

分配内存(是否正确?)

发送结构(如何获得整个s_OUTDATA结构的正确大小?)


接收器

初始化结构:

typedef struct soutputdata {
    unsigned long long ull_date;
    unsigned int    ui_ixl;
    unsigned int    ui_type;
    unsigned int    ui_index;
    char c_values[64][2];
    int i_valueid;
} s_OUTPUTDATA;

typedef struct sheader {
    int i_head;
} s_HEADER;

typedef struct soutdata {
    s_HEADER *sHeader;
    s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
typedef struct soutputdata {
    unsigned long long ull_date;
    unsigned int    ui_ixl;
    unsigned int    ui_type;
    unsigned int    ui_index;
    char c_values[64][2];
    int i_valueid;
} s_OUTPUTDATA;

typedef struct sheader {
    int i_head;
} s_HEADER;

typedef struct soutdata {
    s_HEADER *sHeader;
    s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
分配内存(是否正确?)

接收结构:

if ((num = recv(newSocket, p, 1024,0)) == -1) {
   perror("recv");
   exit(1);
}
else if (num == 0) {
   printf("Connection closed\n");
}
send(sendSocket, p, sizeof(s_OUTDATA), 0)
有什么问题吗?

当尝试处理接收到的数据时,我得到一个分段错误

printf("ui_index: %d\n", p->sDATAout->ui_index);
我错过了什么?


我假设我在内存分配方面做错了什么,但我不确定该怎么解决。

看看你发送的结构:

typedef struct soutdata {
    s_HEADER *sHeader;
    s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
它不包含
s_头
s_输出数据
实例,而是指向这些结构的指针。所以你不是在发送数据,而是在发送指针

由于指针地址只对创建它们的进程有意义,因此接收端的这些指针不会指向有效的内存位置,因此取消引用这些指针会导致错误

将结构更改为包含实际数据,而不是包含指针:

typedef struct soutdata {
    s_HEADER sHeader;
    s_OUTPUTDATA sDATAout;
} s_OUTDATA;
然后发送,给出结构的大小:

if ((num = recv(newSocket, p, 1024,0)) == -1) {
   perror("recv");
   exit(1);
}
else if (num == 0) {
   printf("Connection closed\n");
}
send(sendSocket, p, sizeof(s_OUTDATA), 0)
您需要解决的另一个问题是尾数结构填充

一些系统存储整数类型时,首先使用最低有效字节(LSB),而其他系统则首先使用最高有效字节(MSB)。
htonl
htons
函数可以分别将32位和16位值从主机字节顺序(LSB或MSB)转换为网络字节顺序(MSB),而
ntohl
ntohs
执行这两个函数的相反操作

struct
可能在元素之间或末尾包含一定量的填充。填充的布局取决于实现。因此,一个系统上的
结构的二进制布局可能与另一个系统上的不同


处理填充可以通过单独发送每个数据字段而不是整个结构来解决,以便发送的数据采用已知格式。或者,您也可以使用来构建结构,从而在最后消除填充或将其减少到已知的数量。

感谢您的快速回复。哇,完全错过了。但是现在我在处理这两个结构的指针时遇到了一个编译错误(因为它们不再存在)。我是否需要将所有内容都更改为实例?@Frechdachs是的,因为成员的数据类型已更改,所以需要说明它们的使用方式。也就是说,
p->sHeader.I_head
而不是
p->sHeader->I_head
。好吧,该死。因为我有一个函数,它的指针指向s_OUTPUTDATA结构作为返回,现在我需要返回整个结构,它太重了。或者我可以将指针内容强制转换为实例吗?@Frechdachs根据函数的使用方式,您可能仍然可以使用指针。不是返回一个,而是将一个作为函数将填充的参数(作为该类型变量的地址)传入。