C++ 如何通过套接字(TCP)进行二进制序列化

标签 c++ c sockets

抱歉我的英语不好。

背景:

我有 6 个变量

  1. 无符号字符
  2. 字符
  3. 无符号短
  4. 整数
  5. 整数
  6. 整数

我序列化此数据以准备发送到套接字。

问题,我如何存储序列化数据并发送它?

我的第一个解决方案,使用结构来发送我的数据,但这个解决方案需要强制转换,并且强制转换操作非常慢。

除了将我的变量存储在结构中之外,您还有更好的解决方案吗?

#include <sstream>
#include <string.h>

typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;

#define PORT 4241
template<typename T>
inline std::ostream& raw_write(std::ostream &os, const T &t)
{
  return os.write( reinterpret_cast<const char*>(&t), sizeof t);
}

int main()
{
  char protocole;
  char id_module;
  unsigned short id_message;
  int id_client;
  int size_msg;
  unsigned long timestamp;

  SOCKET csock;
  SOCKADDR_IN csin;

  protocole = 1;
  id_module = 2;
  id_message = 256;
  id_client = 8569;
  size_msg = 145;
  timestamp = 1353793384;
  csock = socket(AF_INET, SOCK_STREAM, 0);
  csin.sin_addr.s_addr = inet_addr("127.0.0.1");
  csin.sin_family = AF_INET;
  csin.sin_port = htons(PORT);
  connect(csock, (SOCKADDR*)&csin, sizeof(csin));
  raw_write(ss, protocole);
  raw_write(ss, id_module);
  raw_write(ss, id_message);
  raw_write(ss, id_client);
  send(csock, ss.str().c_str(), strlen(ss.str().c_str()), 0);
  close(csock);

}

不起作用,因为字符串包含“\0”并发送剪切它。

我说过,在发送许多数据时,转换速度很慢。在接收时我需要再次转换以恢复我的数据。

此操作比仅读取字节更慢。

最佳答案

如果你不想从头开始,你可以使用 Google Protocol Buffers 。它是一个强大的库,可让您定义一个协议(protocol),该协议(protocol)只不过是一个类,可以将自身序列化为流、文件、缓冲区或字符串(反序列化为流、文件、缓冲区或字符串)。

我自己使用它,将其序列化为易于通过套接字发送的字符串很不错。

编辑:回复评论:

好吧,请注意它不会 send (...) 截断您的流。它的 c_str() 以 '\0' 结尾。也许您应该尝试避免流并使用提供对其原始数据的访问的容器,例如带有 const void * data() 的 std::string 或 std::vector 。您可以将其和 size() 传递给 send(...)

关于C++ 如何通过套接字(TCP)进行二进制序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13601945/

相关文章:

c - 套接字,使用 SOCK_DGRAM、epoll 进行客户端服务器通信

sockets - NestJS多个WebSocketGateway

c++ - 在代码中定义指令以分隔代码版本

c++ - DsMakeSpn 在 Windows Server 2008 上总是失败

c - 位打包和动态分配的问题

C中的客户端服务器程序

c++ - 从管道 block 和死锁中读取

c++ - 循环中的预递增/递减与使用 gcc 和 Visual C 的递增/递减

c - 为什么数组变量的地址与自身相同?

用于收集仅包含主要实体的 IP 地址的所有主机名的 Python 脚本