【问题标题】:Sending a structure through a socket in c通过c中的套接字发送结构
【发布时间】:2017-12-06 00:05:20
【问题描述】:

我想通过一个用 C 语言编写的 tcp 服务器/客户端程序中的套接字发送数据结构。但是,当我尝试打印发送的数据时,它不会打印任何内容。我现在已经意识到以这种方式发送结构是一个坏主意,我所看到的帖子对于找到一种真正实现这项工作的方法并不是很有帮助。这是有问题的数据结构:

#define BUFFSIZE 1024
#define USERLEN 32
#define OPTLEN 16

struct  message{
  char option[OPTLEN];
  char user[USERLEN];
  char buff[BUFFSIZE]; 
  char target[USERLEN];
  int sockid;
};

提前致谢。

【问题讨论】:

  • 您是否已通读此之前对一个非常相似的问题的回答。在什么时候这对你不起作用? stackoverflow.com/questions/8000851/…
  • 只需将其转换为 char 数组以对其进行序列化,如果您需要将其限制为实际的字符,则只需 base64 对其进行编码
  • 唯一可能导致问题的部分是sockid。有一个问题是您的buff 实际包含 1000 多个字符而不是几个字符的频率;为这么长的字段只发送活动字符可能会更好,但其他人可能会被完整发送。查找“序列化”——这是您发送数据所需的过程,以及接收数据所需的“反序列化”。
  • 如果你想使用二进制协议,我建议谷歌的 protobuf :)

标签: c sockets data-structures tcp structure


【解决方案1】:

对于相同的机器和编译器,您可以执行以下操作:

// define your structure:
#define BUFFSIZE 1024
#define USERLEN 32
#define OPTLEN 16

typedef struct message{
  char option[OPTLEN];
  char user[USERLEN];
  char buff[BUFFSIZE]; 
  char target[USERLEN];
  int sockid;
}my_message;


// now you can use it in your program

my_message m;

// initialize m
...
strcpy(m.user,"1234");
...
m.sockid = sockfd;

// send it over 

if ((nbytes = write(sockfd, &m, sizeof(my_message)) != sizeof(my_message))
{
  printf("error writing my message");
}



// read the message on the other side:
...
my_message received_message;
int size;

if( (size = recv ( sockfd, (void*)&received_message, sizeof(my_message), 0)) >= 0)
{
     // check the size
}

// It would work for same machines 32/64 bits and same compilers.

如果您需要更好的可移植性,请尝试protobuf-cnanopb、二进制序列化binntpl

【讨论】:

    【解决方案2】:

    你可以在套接字上写出消息:

    struct message mymess;
    ...
    write(socketfd, &mymess, sizeof(struct message));
    

    然后在客户端读回它。如果它总是相同的硬件/编译器,那会起作用,因为结构将以相同的方式编译。如果你没有 memset() 整个 mymess,那么你可能在 write() 中有未初始化的东西。它应该是安全的,但可以引发健全性检查。

    要获得更可靠的消息传递,您需要设计或采用序列化协议。 JSON 是一种非常流行的格式(尽管可能不在 C 程序员中),但还有很多其他格式。

    【讨论】:

      【解决方案3】:

      在编写结构之前,您需要注意填充问题。看来您的结构很好地对齐。但是,接收器需要具有相似的架构和相似的编译器结构打包设置,才能以相同的方式使用该结构。或者,您可以定义一个消息协议,显式打包此数据并以字节流的形式写入。

      也就是说,仍然可以简单地编写结构 写(袜子,&myMessage,sizeof(消息))。它将写出 sizeof(message) 的所有字节。

      【讨论】:

        猜你喜欢
        • 2016-06-06
        • 2015-01-02
        • 2013-07-22
        • 2016-01-11
        • 1970-01-01
        • 1970-01-01
        • 2017-04-24
        • 2010-11-22
        相关资源
        最近更新 更多