c# - 使用tcp将 float 组从c++发送到c#

标签 c# c++ sockets tcp

我是 tcp 的新手,已经设置了两个应用程序,一个用 c++ 发送数据,另一个用 c# 接收数据。 我发送了两个 float 组,每个数组包含三个 float 。

数据传输和解包都很好,但数据的顺序不一致。比如我发送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: %d\n", 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;
                            }

我这里的错误是什么?我应该单独发送花车吗? 谢谢。

最佳答案

第一个错误 是假设您将收到与您发送的数据完全相同的数据。

不幸的是,当发送多个 float 时,接收者可能会一起接收它们(正如您所期望的),但它也可以接收几部分(在假设的最坏情况下逐字节接收)。

所以在你的 while 循环中,你可能只收到 10 个字节,但你假设已经收到 24 个字节。导致大量垃圾。

解决方案: 在假设数据存在之前,先用 rc 检查您是否收到了正确数量的数据,并以正确管理缓冲区的方式实现循环(即第一个数据的接收结束组数据,可能与下一个序列的开始一起出现)。

还有一个第二个更微妙的问题:只有当源和目标使用相同的浮点编码时,您的代码逻辑才有效。 C++ 标准不修复此编码(它通常是 IEEE-754,但不一定是,即使是不同的 endianness could affect the order of the bytes 通过网络发送)。

如果您只针对 wintel 平台,这可能不是问题。但我认为值得一提,以防您的 C++ 部分用于使用不同架构的 IoT 设备;-)

编辑:处理缓冲接收的提示

我对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 
    }

关于c# - 使用tcp将 float 组从c++发送到c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35958416/

相关文章:

c++ - 将结构复制到具有 const 值的数组

c++ - 调试多线程应用程序

java - scala 和 java io 和套接字问题

c# - WSDL Web 服务从 C# 返回空数组

c# - 无法并行读取同一个文件

c# - 如何针对一组可变的值范围进行验证?

c - 通过网络与远程服务器交互

c# - WPF 树数据绑定(bind)模型和存储库

c++ - Visual C++ 2008 中的默认项目

Perl、ClamAV、扫描流中的病毒