【问题标题】:Send float array from C++ server to C# client将浮点数组从 C++ 服务器发送到 C# 客户端
【发布时间】:2011-07-24 01:19:47
【问题描述】:

我正在尝试将一些数据从 C++ 服务器发送到 C# 客户端。我能够发送 char 数组。但是浮点数组存在一些问题。

这是C++服务器端的代码

float* arr;
arr = new float[12];
//array init...
if((bytecount = send(*csock, (const char*)arr, 12*sizeof(float), 0))==SOCKET_ERROR){
}

所以是的,我正在尝试发送一个大小为 12 的浮点数组。

这是客户端的代码。 (奇怪的是,从一开始就没有简单的方法将浮点数从流中取出。我以前从未使用过 C#,也许有更好的方法?)

//get the data in a char array 
streamReader.Read(temp, 0, temp.Length);  
//**the problem lies right here in receiving the data itself

//now convert the char array to byte array
for (int i = 0; i < (elems*4); i++)           //elems = size of the float array
{
    byteArray = BitConverter.GetBytes(temp[i]);
    byteMain[i] = byteArray[0];
}

//finally convert it to a float array
for (int i = 0; i < elems; i++)
{
    float val = BitConverter.ToSingle(byteMain, i * 4);
    myarray[i] = val;
}

看看两边的内存转储问题就清楚了-

//c++ bytes corresponding to the first 5 floats in the array
//(2.1 9.9 12.1 94.9 2.1 ...)
66 66 06 40    66 66 1e 41     9a 99 41 41    cd cc bd 42    66 66 06 40

//c# - this is what i get in the byteMain array
66 66 06 40    66 66 1e 41     fd fd 41 41    fd 3d  ? 42    66 66 06 40

在 c# 方面这里有 2 个问题- 1)首先它不处理高于0x80(高于127)的任何东西(不兼容的结构?) 2) 出于某种令人难以置信的原因,它掉了一个字节!!

这发生在接收数据时的“临时”中

我一直在想办法,但还是一无所获。 您知道为什么会发生这种情况吗?我确定我做错了什么... 有更好方法的建议吗?

非常感谢

【问题讨论】:

    标签: c# c++ sockets


    【解决方案1】:

    从您的代码中不清楚streamReader 变量指向什么(即它的类型是什么?)但我建议您改用BinaryReader。这样一来,您就可以只读取数据 one float at a time,而完全不用担心 byte[] 数组:

    var reader = new BinaryReader(/* put source stream here */)
    var myFloat = reader.ReadSingle();
    // do stuff with myFloat...
    // then you can read another
    myFloat = reader.ReadSingle();
    // etc.
    

    不同的读者对数据做不同的事情。例如,文本阅读器(和流阅读器)将假定所有都是特定编码(如 UTF-8)的文本,并可能以您意想不到的方式解释数据。 BinaryReader 不会这样做,因为它旨在让您准确指定要从流中读取的数据类型。

    【讨论】:

    • StreamReader 被定义为System.IO.StreamReader(&lt;NetworkStream&gt;)。是的,我认为BinaryReader 可能是一个更好的选择。谢谢让我试试看。
    【解决方案2】:

    我不确定 C#,但 C++ 不保证浮点数(或任何其他数据类型)的内部二进制表示。众所周知,0.42 可能用这 4 个字节表示:'0'、'.'、'4'、'2'。

    最简单的解决方案是传输人类可读的字符串,例如“2.1 9.9 12.1 94.9 2.1”并使用 cin/cout/printf/scanf 和朋友。

    【讨论】:

    • printf 是否保证输出的形式?
    • 理论上我同意,但实际上,与 IEEE 754(定义双精度和浮点数)相比,真的有任何不同的浮点表示吗?
    • (顺便说一句,c# 确实将 float 和 double 的格式指定为上述标准中定义的)msdn.microsoft.com/en-us/library/aa691146(v=vs.71).aspx
    • 否,但可以免费使用实现,例如,floats 的双精度。我没有标准,所以我无法检查,但关键是在编写可移植程序时必须这样做。字节顺序是另一个需要警惕的问题。并感谢 C# 位。
    • @svick:是的,但必须注意当前的语言环境。
    【解决方案3】:

    在网络中,您应该始终将您的数字转换为通用格式,然后再读回。换句话说,除了字节之外的任何数据都应该被封装。因此,无论您使用哪种编程语言,这都是您需要做的。我无法评论您的代码有什么问题,但这可能会解决您的问题,并且以后会省去一些麻烦。考虑架构是 64 位还是使用不同的字节序。

    编辑:
    我猜你的问题在于有符号未签名,可以用 Isak 的回答来解决,但请记住我所说的。

    如果您在封装方面需要帮助,请查看 Beej 的网络指南。它应该有一个如何通过网络对浮点数进行编码的示例。

    【讨论】:

    • 是的,我知道这一点。只是如果你看到内存转储,一些浮点数会很好地传输!
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多