[英]Passing structure over TCP socket in C
我正在用C编写一个小型客户端服务器应用程序。
在客户端我有一个结构,如,
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _viewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_send ;
#pragma pack(0) // turn packing off
并填充变量,
struct _viewBoxClient_Info client_info;
client_info.bRT_flag= 10;/*0 for false, 1 for true*/
client_info.viewBoxID=10000;
memcpy(client_info.frameData,buf,sizeof(client_info.frameData)); //char buf[] data is "is 1st line"
client_info.nFrameNum=1;
并使用以下功能发送到服务器,
send(sock, (char *)&client_info, bytesRead, 0);
在服务器端,我有一个结构(与客户端结构相同),
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _lclviewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_receive ;
#pragma pack(0) // turn packing off
并接收消息并在屏幕上打印,
viewBoxClient_info_receive lcl_viewBox;
ssize_t bytesReceived = recv( *nfd, &lcl_viewBox, sizeof(struct _lclviewBoxClient_Info), 0);
printf("\nlcl_viewBox.bRT_flag:%d\n",lcl_viewBox.bRT_flag);
printf("lcl_viewBox.nFrameNum:%d\n",lcl_viewBox.nFrameNum);
printf("lcl_viewBox.frameData:%s\n",lcl_viewBox.frameData);
服务器屏幕上的O / p,
lcl_viewBox.bRT_flag:1
lcl_viewBox.nFrameNum:1936287860
lcl_viewBox.frameData: is 1st line
我不知道它在我的服务器端发生了什么。 我从客户端发送10个bRT_flag,在服务器上接收1个。 还从客户端发送nFrameNum = 1并在服务器上以nFrameNum:1936287860接收。 frameData也在客户端我发送“这是第一行”,在服务器接收“只是第一行”。 有人会帮助摆脱这个问题吗?
感谢致敬,
斯里兰卡
不应该这样:
send(sock, (char *)&client_info, bytesRead, 0);
是:
send(sock, (char *)&client_info, sizeof( client_info ), 0);
你应该检查send()的返回值,特别是recv()的返回值 - 无法保证对recv的调用将一次性获取你的结构。
像这样发送原始结构是一个非常糟糕的主意。
您必须处理字节顺序(字节顺序),打包(即使使用#pragma pack
仍然可能存在问题),另一个问题是像'int'这样的类型的大小可能因平台而异。
我建议像Google Protocol Buffers这样的序列化库来帮助你解决这个问题。 如果你仍然想自己做,你需要查找像htonl
这样的函数将整数类型转换为网络字节顺序,并开始使用固定大小的原语,如uint32_t
等。
您还应该立即停止发送整个结构,而是编写帮助函数,如writeClientStruct(int sock,struct client_struct *),它将分别发送每个成员值以避免平台之间的打包问题。
一种解释是您的客户端和服务器对“unsigned long”的大小有不同的解释。 (在不同的机器或不同的编译器选项上运行,其他是32位和其他64位)。
这可以解释症状:
对此进行简单检查将检查sizeof(结构)或sizeof(unsigned long)以查看它们是否匹配。
请参阅Mike Weller的帖子,了解如何正确解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.