1

我正在尝试按照Beejs Guide to UNIX IPC在两个 C++ 程序之间设置一个 UNIX 套接字服务器/客户端,但是示例代码仅演示了发送和接收 char 数组。我已经在这里看到有人声称最好的选择是将双精度值转换为字符,但是由于我想在一秒钟内多次传递值,所以我想避免这种类型的转换。现在我正在尝试将指针传递给某个双精度,但我不知道如何获取另一侧的值。在我正在做的套接字客户端中:

...
double number = 453.23;
send(s, &number, sizeof(number), 0);

但我觉得这不是正确的做法。

4

4 回答 4

3

假设双方对doubles 具有相同的表示(包括字节序),在套接字的另一侧,您可以执行基本相同的操作:

double number;
recv(s, &number, sizeof(number), 0);

(当然假设您只是在传输doubles 或者您有某种协议,并且在程序的这一点上您确定发件人已经发送了您的double

如果不能保证字节顺序,那么您必须为传输决定字节顺序并适当地交换字节;最后,如果连 FP 类型的基本表示都不能保证,你最好的选择可能只是把数字写成文本,做相关的sscanf/ sprintf

于 2013-06-08T21:15:45.417 回答
1
  1. 如果“每秒几次”真的只是每秒“几次”(即几十甚至几百或几千)次,那么转换为 char 数组应该不会对性能产生严重影响。

  2. 但是无论如何,您都不需要这种转换。如果您使用的是 IPC,那么这两个程序很可能在同一台机器上物理运行 - 如果您发送标量数据的原始内存表示,它将在接收端以相同的方式解释(这不适用于当然是指针)。除非您不想跨平台(从某种意义上说,您不想在两种不同的架构之间交换数据),否则不要担心正确的序列化。

于 2013-06-08T21:11:41.040 回答
1

我已经制作了一些发送二进制值的套接字程序:整数和双精度值,但为了做到这一点,您必须确定两台机器(服务器和客户端)都是二进制兼容的(字节顺序)。确保在两台机器中,双精度 (sizeof(double)) 的大小相同,均为 8 个字节。英特尔机器和平板电脑 Android 就是这种情况,它们在 C#、C++、Java 和 Delphi 中是相同的。我还在平板电脑(Android 和 Java)之间进行二进制传输到 Windows XP 和 7 中用 C# 编写的程序,它可以工作。

请记住,它不会是可移植的,并且应该在移植到其他平台之前进行测试。

我会给你一些例子:

C++

// Sender
Send(socket, &MyDouble, sizeof(MyDouble), 0);

// Reader
Recv(socket, &MyDouble, sizefof(MyDouble), 0);

爪哇:

// Sender
ByteBuffer buff = ByteBuffer.allocateDirect(8);
buff.order(ByteOrder.LITTLE_ENDIAN); // To Intel machines
buff.putDouble(MyDouble);
Socket.getOutputStream().write(buff.array(), 0, 8);

// Reader 
byte[] data new byte[8];
Socket.getInputStream().read (data, 0, 8);
ByteBuffer buff = ByteBuffer.wrap(data);
buff.order(ByteOrder.LITTLE_ENDIAN); // From Intel machines
MyDouble = buff.getDouble();
于 2013-06-08T22:02:32.853 回答
1

通过套接字传输的信息没有您在编程语言中理解的数据类型。Char 数组本质上是字节数组(取决于 C 标准)。请参阅此处了解更多信息

您可以传输您拥有的双精度,然后尝试从接收到的字节进行转换,或者您可以以某种方式对其进行序列化,然后反序列化。如果你的应用程序由于糟糕的实现或假设而崩溃或发展出未定义的行为,那么每秒几次毫无意义。

当您通过套接字发送/接收数据时,请小心进行大量错误检查,因为假设是一切之母......

恕我直言,将您的数据封装为 JSON、XML 或其他形式,以便双方准确了解正在传输的内容。

编辑:如果您使用的是 IPC,您还不如设置一个共享内存?

于 2013-06-08T21:15:11.980 回答