我正在用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也在客户端我发送“这是第一行”,在服务器接收“只是第一行”。 有人会帮助摆脱这个问题吗?
感谢和问候,
斯
答案 0 :(得分:2)
不应该这样:
send(sock, (char *)&client_info, bytesRead, 0);
是:
send(sock, (char *)&client_info, sizeof( client_info ), 0);
你应该检查send()的返回值,特别是recv()的返回值 - 不能保证调用recv会一次性获取你的结构。
答案 1 :(得分:2)
发送这样的原始结构是一个非常糟糕的主意。
你必须处理字节顺序(字节顺序),打包(即使使用#pragma pack
仍然可能存在问题),而另一个问题是像'int'这样的类型的大小可能因平台而异。
我建议使用像Google Protocol Buffers这样的序列化库来帮助您。如果您仍想自己动手,则需要查找htonl
等函数,将整数类型转换为网络字节顺序,并开始使用uint32_t
等固定大小的原语。
您还应该立即停止发送整个结构,而是编写helCl函数,如writeClientStruct(int sock,struct client_struct *),它将分别发送每个成员值,以避免平台之间的打包问题。
答案 2 :(得分:0)
一种解释是您的客户端和服务器对“unsigned long”的大小有不同的解释。 (在不同的机器或不同的编译器选项上运行,其他是32位和其他64位)。
这可以解释症状:
对此进行简单检查将检查sizeof(结构)或sizeof(unsigned long)以查看它们是否匹配。
请参阅Mike Weller的帖子,了解如何正确解决此问题。