从结构,套接字编程发送数据

我有一个学校的任务,一部分是使用套接字编程从客户端向服务器发送一组int,chars char *。 发送整数或字符的工作正常,但有没有办法将整个结构作为一个数据包发送? 阅读有关序列化的内容,但我似乎无法使其正常工作。 这是一段代码:

The struct looks like this: struct Msg { int a; char b; char *user; }; Client: init variables and such... int netcom(char* ip, int port) { sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // clear the structure bzero(&serveraddr, sizeof(struct sockaddr_in)); serveraddr.sin_family = AF_INET; // add the server adress inet_pton(AF_INET, ip, &serveraddr.sin_addr); // add the port number serveraddr.sin_port = htons(port); // connect connect (sd,(struct sockaddr*)&serveraddr, sizeof(struct sockaddr_in)); } int sendPkg(struct Msg msg) { send(sd, &msg, sizeof(msg), 0); } 

接收的服务器部分如下所示:

 char buf[100]; recv(sd[i], buf, sizeof(buf)-1, 0); 

客户端发送完全正常,服务器收到罚款。 但我不知道我要发送什么,以及如何正确阅读。 所以这是我的问题。 如何使用套接字从struct正确发送数据。

直接发送一个结构看起来很吸引人,因为你可以在一次调用中完成它……更糟糕的是:有时它实际上会很棒! 虽然这是一个陷阱。

这是一个陷阱的第一个原因是,在你的情况下,例如,其中一个元素是一个指针。 除非在极少数情况下,接收器将获得在该端无用的指针 – 指针指向对发送进程有效的内存。

第二个也是不太明显的原因是这个陷阱是套接字一侧结构的布局(在内存中)在另一侧可能不相同。 这是机器架构和编译器设置的一个function,因此相信它“只是没问题”是不安全的。 这个陷阱很容易逃脱一段时间,特别是在开发过程中,您可能在测试的每一侧都有兼容的体系结构。

你最好的选择是单独发送每个字段,即使这很痛苦。 通过为此结构创建专用的发送器和接收器function,您可以通过在代码中应用一些面向对象的设计来减轻痛苦。 这些函数对内容和顺序有深入的了解,并将其打包成较小的发送(在char *的情况下,可能需要在字符串数据之前包含一个长度)。

如我所描述的打包发送只要结构没有从套接字的一侧改变到另一端,但你可能想要警惕在一端有不同版本的结构……说一个新的(或不存在的)字段。 要处理这个问题,你可以考虑标记你发送的数据(而不是假设“首先我们发送a ,然后是b ,等等”)。

查看许多JSON库来管理序列化将是有益的。 这为您提供了一种易于阅读的格式,可以解决我在这里提出的所有问题,并且几乎所有常见的编程语言都有JSON库。