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

标签 c sockets struct send recv

我有一项学校作业,其中一部分是使用套接字编程将一组整数、字符 char* 从客户端发送到服务器。发送 int 或 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 正确发送数据。

最佳答案

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

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

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

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

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

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

关于c - 从结构体发送数据,套接字编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20000257/

相关文章:

c - 如何查看输入文件的第一个字符是否为数字? C编程

Windows API 编程中的组合框

Cocoa-如何使用 ARC 制作 TCP 套接字?

c - 使用指针和数组时关于不兼容指针类型赋值的警告?

C 代码将结构体传递给函数堆栈溢出

c - C语言删除文件中的一行

c - char* 究竟定义了什么?如果它定义了一个字符串数组,我如何输出单个元素?

ios - iOS 中的 IRC/TOPIC 命令修整问题

php - 适用于 Windows 服务器和 Cisco 交换机的简单 PHP 正常运行时间监视器

pointers - 在 Go 中修改结构中的结构 slice