简体   繁体   English

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

[英]Sending data from a struct, socket programming

I have an assignment for school, and one part is to send a set of ints, chars char* from a client to a server using socket programming. 我有一个学校的作业,一部分是使用套接字编程将一组int chars char *从客户端发送到服务器。 Sending ints or chars works just fine, but is there any way to send the entire struct as one packet? 发送整数或字符可以正常工作,但是有什么办法可以将整个结构作为一个包发送? Read about serializing, but I cant seem to make it work. 了解有关序列化的信息,但我似乎无法使其工作。 Here's a code snippet: 这是一个代码片段:

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); 
}

And the part of the server that receives looks like this: 服务器接收的部分如下所示:

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

The client sends perfectly fine, and the server receives fine. 客户端发送完全正常,而服务器收到很好。 But I have no idea what I'm sending, and how to read it properly. 但是我不知道我要发送什么,以及如何正确阅读。 So that's my question. 这就是我的问题。 How to properly send over the data from a struct using sockets. 如何使用套接字正确地从struct发送数据。

Sending a struct directly seems appealing because you can do it in a single call... and worse: sometimes it will actually work out great! 直接发送结构似乎很吸引人,因为您可以在一个调用中完成它……更糟的是:有时它实际上效果很好! It's a trap though. 这是一个陷阱。

The first reason this is a trap is that, in your case for example, one of the elements is a pointer. 这是一个陷阱的第一个原因是,例如,在您的情况下,其中一个元素是指针。 Except in very rare cases, the receiver will get that pointer which is useless on that end -- the pointer points to memory that is valid for the sending process. 除非在极少数情况下,否则接收方将获得该端无用的指针,该指针指向对发送过程有效的内存。

The second, and less obvious reason this is a trap is that the layout (in memory) of a structure on one side of a socket might not be identical on the other side. 第二个不太明显的原因是陷阱,原因是套接字一侧的结构(在内存中)在另一侧的布局可能不相同。 This is a function of machine architectures and compiler settings, making it unsafe to trust that it will "just be ok". 这是计算机体系结构和编译器设置的功能,因此很难相信它会“正常”。 This trap is easy to get away with for a while, especially during development, where you're likely to have compatible architectures on each side of your test. 这种陷阱很容易摆脱一段时间,尤其是在开发过程中,在测试过程中,您可能在测试的每一侧都具有兼容的体系结构。

Your best bet is to send each field individually, even though that is painful. 最好的办法是单独发送每个字段,即使这样很痛苦。 You can make it less painful by applying a little object oriented design to your code though, by creating a dedicated sender and receiver function for this structure. 但是,通过为此代码创建专用的发送器和接收器功能,可以通过对代码应用一些面向对象的设计来减轻痛苦。 These functions have intimate knowledge of the contents and order, and package it into smaller sends (which, in the case of your char * , probably need to include a length before the string data). 这些函数非常了解内容和顺序,并将其打包为较小的发送(对于char * ,可能需要在字符串数据之前包含一个长度)。

A packaged send as I described is fine as long as the structure hasn't changed from one side of the socket to the other, but you might want to be wary of having a different version of the structure on one end... say a new (or not present) field. 正如我所描述的,打包发送可以很好,只要结构没有从套接字的一侧更改为另一侧即可,但是您可能要警惕在一端使用不同版本的结构...说一个新(或不存在)字段。 To handle this, you could consider tagging the data you send (rather than assuming "first we send a , then b , etc."). 为了解决这个问题,您可以考虑标记发送的数据(而不是假设“首先发送a ,然后b等”)。

It would be beneficial to look into the many JSON libraries to manage your serialization. 研究许多JSON库来管理序列化将是有益的。 This gives you an easy to read format that addresses all of the issues I've presented here, and there are JSON libraries available for nearly every common programming language. 这为您提供了一种易于阅读的格式,可以解决我在此处提出的所有问题,并且几乎所有常见的编程语言都可以使用JSON库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM