【问题标题】:Sending data from a struct, socket programming从结构发送数据,套接字编程
【发布时间】:2013-11-28 19:08:39
【问题描述】:

我有一个学校作业,其中一部分是使用套接字编程从客户端向服务器发送一组 int、chars char*。发送整数或字符工作得很好,但是有没有办法将整个结构作为一个数据包发送?阅读有关序列化的信息,但我似乎无法使其工作。这是一个代码sn-p:

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 正确发送数据。

【问题讨论】:

标签: c sockets struct send recv


【解决方案1】:

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

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

这是一个陷阱的第二个不太明显的原因是套接字一侧的结构的布局(在内存中)在另一侧可能不相同。这是机器架构和编译器设置的一个功能,因此不能安全地相信它会“正常”。这个陷阱在一段时间内很容易摆脱,尤其是在开发过程中,您可能在测试的每一端都有兼容的架构。

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

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

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

【讨论】:

    猜你喜欢
    • 2014-12-09
    • 2018-09-13
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多