繁体   English   中英

通过本地UNIX套接字发送双倍

[英]Send double over local UNIX sockets

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

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

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

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

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

(当然,假设您只发送double或您具有某种协议,并且在程序的这一点上,您可以确定发送方已发送了double

如果不能保证字节序,则必须确定传输的字节序并适当地交换字节。 最后,即使不能保证FP类型的基本表示形式,您最好的选择就是将数字写为文本,并执行相关的sscanf / sprintf

  1. 如果“每秒几下”实际上只是每秒几下(即几十甚至几百或几千),那么转换为char数组应该不会对性能产生严重影响。

  2. 但是您还是不需要这种转换。 如果您使用的是IPC,那么这两个程序很可能在同一台计算机上实际运行-如果您发送标量数据的原始内存表示形式,则它将在接收器端以相同的方式进行解释(这并不适用于指针)。 直到您不想跨平台(就意味着您不想在两种不同体系结构之间交换数据)之前,都不必担心适当的序列化。

通过套接字传输的信息没有数据类型,因为您可以通过编程语言来理解它们。 Char数组本质上是字节数组(取决于C标准)。 在这里查看更多信息

您可以传输所拥有的double,然后尝试从接收到的字节进行转换,也可以以某种方式对其进行序列化,然后反序列化。 如果您的应用由于执行不当或假设不当而崩溃或出现未定义的行为,那么每秒几秒钟就没有任何意义。

当您通过套接字发送/接收数据时,请小心执行大量错误检查,因为所有假设都是假设...

IMHO以JSON,XML或其他形式封装您的数据,以便双方都能准确知道正在传输的内容。

编辑:如果您使用的是IPC,则还可以设置共享内存吗?

我已经制作了一些套接字程序来发送二进制值:整数和双精度数,但是要做到这一点,必须确保两台机器(服务器和客户端)都是二进制兼容的(字节顺序)。 确保两台机器中double的大小(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);

Java:

// 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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM