尽管这可能是一个重复的帖子,但我想确保其在我的特定代码中的工作方式。
我想实现什么?
通过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;
我现在想向连接的TCP客户端发送S_OUTDATA结构。
分配内存(这正确吗?):
s_OUTDATA *poutData = malloc(sizeof(s_OUTDATA));
poutData->sDATAout = malloc(sizeof(s_OUTPUTDATA));
poutData->sHeader = malloc(sizeof(s_HEADER));
发送struct(我如何获得整个S_outdata struct的正确尺寸?):
if ((send(sendSocket, poutData, 1024, 0)) == -1) {
fprintf(errlog, "%.3f error: %s(): Failure Sending Message!n", gettime(), __func__);
close(sendSocket);
}
接收者
初始化结构:
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;
分配内存(这正确吗?):
s_OUTDATA *p = malloc(sizeof(s_OUTDATA));
poutData->sDATAout = malloc(sizeof(s_OUTPUTDATA));
poutData->sHeader = malloc(sizeof(s_HEADER));
接收结构:
if ((num = recv(newSocket, p, 1024,0)) == -1) {
perror("recv");
exit(1);
}
else if (num == 0) {
printf("Connection closedn");
}
有什么问题?
尝试使用收到的数据时,我会得到分割故障。
printf("ui_index: %dn", p->sDATAout->ui_index);
我缺少什么?
我认为我在内存分配中做错了STH,但我不确定如何解决它。
看一下您发送的结构:
typedef struct soutdata {
s_HEADER *sHeader;
s_OUTPUTDATA *sDATAout;
} s_OUTDATA;
这不包含 s_HEADER
和 s_OUTPUTDATA
的实例,而是 pointers 。因此,您不是发送数据,而是发送数据。
,由于指针地址仅对创建它们的过程有意义,因此这些指针在接收方中没有指向有效的内存位置,因此请指出这些指针会导致不确定的行为。
而不是包含指针,而是更改结构以包含实际数据:
typedef struct soutdata {
s_HEADER sHeader;
s_OUTPUTDATA sDATAout;
} s_OUTDATA;
然后发送,给出结构的大小:
send(sendSocket, p, sizeof(s_OUTDATA), 0)
您需要解决的其他内容是 endianness 和结构填充。
有些系统首先存储具有最小字节(LSB)的整数类型,而其他系统则首先从最重要的字节(MSB)开始。htonl
和htons
函数可以从主机字节顺序(LSB或MSB)分别转换32位和16位值为网络字节顺序(MSB),ntohl
和ntohs
执行这两个函数的反面。
struct
可能在元素之间或末尾包含一定数量的填充物。该填充的布局如何取决于实施。因此,一个系统上的struct
的二进制布局可能与另一系统上的二进制布局。
可以通过分别发送每个数据字段而不是整个结构来解决填充,以便以已知的格式发送的数据。或者,您可以使用本指南来结构包装来构建结构,以便在末尾消除填充或将其减少到已知数量。