通过UDP发送任何类型的数据

Ste*_*ane 5 c++ udp

我试着到处寻找但没有运气.这是我的问题:

我有一个UDP套接字,它可以通过任何端口将数据发送到任何IP地址(经过测试和确认工作).

我阅读了很多教程,但他们都在操纵char*[],他们没有指定如何解密它.

我想做什么(伪代码):

客户:

Class my_class;
send (..., my_class, sizeof(my_class),...)
Run Code Online (Sandbox Code Playgroud)

服务器:

receive (sender, buffer, sizeof (buffer))
and do something like
Class my_class = (Class) buffer
Run Code Online (Sandbox Code Playgroud)

所以我的服务器可以分析缓冲区的内容.

但是我迷失了指针,我所能发送的只是char*[],所以我不知道如何来回转换.

Joh*_*ing 6

你不能只是"发送"你的课程.您必须在班级中发送数据的表示.并且向您的班级发送指针也不起作用.当网络上的另一个应用程序收到您的指针时,它们将毫无意义.

考虑一下:

class Data
{
  std::string  name_;
  unsigned value_;
} data;
Run Code Online (Sandbox Code Playgroud)

你不能只是"发送课程".如果您尝试执行以下操作:

send(&data, sizeof(data));
Run Code Online (Sandbox Code Playgroud)

...你最终会向下游客户端发送废话. value_可能会被正确接收,但name_肯定不会.这是因为std::string对象不仅包含构成字符串的字符.还有计数器,指向数据缓冲区的指针,以及谁知道还有什么.字符本身可能甚至不会出现在指示的内存空间中(&data, &data[sizeof(data)])- 这些字符将完全位于其他位置.因此,使用send上面的psudocude,您不仅会发送一堆客户端无法理解的东西,而且通常您甚至不会发送他们能够理解的内容.

输入序列化.序列化只是意味着创建数据对象的表示,可以存储,保存或发送到某个地方,并在以后重新组装.您可以决定此序列化将采用的形状.在data上面的情况下,我们可能决定像这样序列化:

NNNNCCCCCCCC...VVVV
Run Code Online (Sandbox Code Playgroud)

每个字符为1个字节,并且:

  1. N是4个字符的整数,是name_ASCII表示中的字符数
  2. C是N个字节,每个字节是一个字符 name_
  3. V是4个字符的无符号整数,是value_ASCII表示中的值

data上面序列化和发送的一种方法可能是这样的(警告:不是生产质量,未经测试):

stringstream ss;
ss 
  << setw(4) << setfill('0') << right << data.name_.length() << setw(0)
  << data.name_
  << setw(4) << data.value_;

  string buf = ss.str();

  send(buf.c_str(), buf.length());
Run Code Online (Sandbox Code Playgroud)

现在,我们不是尝试发送data,而是发送一个代表的字符串data.如果data是这样创建的:

data.name_ = "foo";
data.value_ = 42;
Run Code Online (Sandbox Code Playgroud)

...然后从套接字发送的字符串将是:

0003foo0042
Run Code Online (Sandbox Code Playgroud)

这可以由客户端接收并重新组装到Data客户端上的新对象,该对象模仿服务器端的内容.

我们上面使用的映射NNNNCCCCCCCC...VVVV- 必须由双方理解.这通常被称为通信协议.

所有应用程序域都使用了无数的协议和序列化方法.它们的范围很简单,就像上面概述的那样,高度压缩和复杂,如FIX/FAST.许多库提供了可满足各种应用程序需求的序列化功能. 想到了Boost.Serialization,我建议你研究一下.

我还有更多的东西在这里掩饰.诸如Endianness,安全性,会话控制......如果你要在客户端或服务器端进行任何重要的网络编程,你就会有很多学习知识.