使用 tcp 将浮点数组从 c++ 发送到 c#
Sending a float array from c++ to c# using tcp
我是tcp的新手,并且设置了两个应用程序,一个在C ++中发送数据,另一个在C#中接收数据。我发送两个浮点数组,每个浮点数包含三个浮点数。
数据传输和解包正常,但数据的顺序不一致。例如,我发送 float1、float2、float3,并接收 float2、float1、float3。
我适用的 c++ 是:
float position[3];
float rotation[3];
for (int i = 0; i < 3; i++)
{
iResult = send(ConnectSocket, (char*)&position[i], (int) sizeof(float),4);
iResult = send(ConnectSocket, (char*)&rotation[i], (int) sizeof(float),4);
}
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %dn", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
//return 1;
}
和 C#:
clientSocket = serverSocket.Accept();
Console.WriteLine("Server: Accept() is OK...");
Console.WriteLine("Server: Accepted connection from: {0}", clientSocket.RemoteEndPoint.ToString());
// Receive the request from the client in a loop until the client shuts
// the connection down via a Shutdown.
Console.WriteLine("Server: Preparing to receive using Receive()...");
while (true)
{
rc = clientSocket.Receive(receiveBuffer);
float transX = System.BitConverter.ToSingle(receiveBuffer, 0);
float transY = System.BitConverter.ToSingle(receiveBuffer, 4);
float transZ = System.BitConverter.ToSingle(receiveBuffer, 8);
float rotX = System.BitConverter.ToSingle(receiveBuffer, 12);
float rotY = System.BitConverter.ToSingle(receiveBuffer, 16);
float rotZ = System.BitConverter.ToSingle(receiveBuffer, 20);
Console.WriteLine(transX + " " + transY + " " + transZ + "n");
Console.WriteLine(rotX + " " + rotY + " " + rotZ + "n");
// Console.WriteLine("Server: Read {0} bytes", rc);
if (rc == 0)
break;
}
我在这里的错误是什么?我应该单独发送浮标吗?谢谢。
第一个错误是假设您将收到与您发送的数据完全相同的数据。
不幸的是,当发送多个浮点数时,接收器可能会将它们全部接收(如您所料),但它也可以分几部分接收它们(在假设的最坏情况下,逐字节接收)。
因此,在 while 循环中,例如您可能只接收 10 个字节,但您假设已经接收了 24 个字节。导致很多垃圾。
解决方案:在假设数据存在之前,请与 rc 一起检查您是否收到了正确数量的数据,并以正确管理缓冲区的方式实现循环(即接收第一组数据的结束可能与下一个序列的开始一起)。
还有第二个更微妙的问题:仅当源和目标使用相同的浮点编码时,代码逻辑才有效。 C++标准没有修复这种编码(它通常是IEEE-754,但不一定是,即使它是,不同的字节序可能会影响通过网络发送的字节顺序)。
如果您仅针对 wintel 平台,这可能不是问题。但我认为值得一提的是,如果您的C++部分是针对使用不同架构的物联网设备;-)
编辑:处理缓冲接收的提示
我不精通 C#,但原理是这样的:
Console.WriteLine("Server: Preparing to receive using Receive()...");
rc=1;
br=0; // number of bytes in buffer
sf=24; // size of one sequence to be received
while (true)
{
while (br<sf && rc>0) { // fill buffer until all bytes of one sequence are there
rc = clientSocket.Receive(receiveBuffer, br, sf-br,SocketFlags.None);
br += rc;
}
if (rc == 0) {
if (br>0)
Console.WriteLine("Server: interupted while receiving data...");
break;
}
//... here you can convert the content of the buffer
}
您发送浮点数的顺序如下所示:
pos1
rot1
pos2
rot2
pos3
rot3
但是,在接收它们时,您将像这样处理数据:
pos1
pos2
pos3
rot1
rot2
rot3
这里的解决方案是从正确的索引读取浮点数。
float transX = System.BitConverter.ToSingle(receiveBuffer, 0);
float transY = System.BitConverter.ToSingle(receiveBuffer, 8);
float transZ = System.BitConverter.ToSingle(receiveBuffer, 16);
float rotX = System.BitConverter.ToSingle(receiveBuffer, 4);
float rotY = System.BitConverter.ToSingle(receiveBuffer, 12);
float rotZ = System.BitConverter.ToSingle(receiveBuffer, 20);
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '