C:通过TCP套接字发送嵌套结构
虽然这可能是一篇重复的文章,但我想确定它在我的特定代码中是如何工作的 我想要实现什么? 通过TCP/IP连接发送和接收结构 到目前为止我有什么? 发送方 初始化结构: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
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根据函数的使用方式,您可能仍然可以使用指针。不是返回一个,而是将一个作为函数将填充的参数(作为该类型变量的地址)传入。