在 Boost ASIO 服务器和 Java 客户端之间通过 TCP 发送双精度

Posted

技术标签:

【中文标题】在 Boost ASIO 服务器和 Java 客户端之间通过 TCP 发送双精度【英文标题】:sending doubles via TCP between Boost ASIO server and Java client 【发布时间】:2013-08-08 16:49:58 【问题描述】:

我正在尝试使用单个 Java 客户端设置一个简单的 Boost ASIO 服务器。

我能够在两者之间发送和成功接收字符串。但是,当我尝试发送双精度值时,另一端只会出现垃圾。

下面是显示我的基本设置的独立代码(带有 C++ Boost ASIO 服务器和 Java 客户端)。当它们运行时,它们会执行以下四个顺序任务:

    客户端向服务器发送一个字符串,服务器接收成功并打印出来。 服务器向客户端发送字符串,接收成功并打印出来。 客户端向服务器发送一个双精度值,服务器收到但不打印 正确。 服务器向客户端发送一个双精度值,客户端收到但不打印 正确。

有谁知道我做错了什么?诚然,我对网络(和 Java)非常陌生。我已经阅读了 Boost ASIO 文档和示例,但知道是否有用。

C++ Boost ASIO 服务器代码:

#include <iostream>
#include <string>

#include <boost/asio.hpp>
#include <boost/array.hpp>

using boost::asio::ip::tcp;

int main()

   unsigned short const PORT = 19876;

   try
   
      boost::asio::io_service ioService;
      tcp::acceptor acceptor(ioService, tcp::endpoint(tcp::v4(), PORT));

      while (true)
      
         // Listen for clients
         std::cout << "Listening for client..." << std::endl;
         tcp::socket socket(ioService);
         acceptor.accept(socket);
         std::cout << "Client heard..." << std::endl;

         size_t len;

         // Receive string from client and print it out
         boost::array<char, 128> cBuf;
         len = socket.read_some(boost::asio::buffer(cBuf, sizeof(cBuf)));
         std::cout.write(cBuf.data(), len);

         // Send string to client
         std::string message = "Server string to send to client\n";
         boost::asio::write(socket, boost::asio::buffer(message));

         // Receive double from client and print it out
         double dVal1 = -1.0;
         char * p_dVal1 = reinterpret_cast<char *>(&dVal1);
         len = socket.read_some(boost::asio::buffer(p_dVal1, sizeof(double)));
         std::cout << dVal1<< std::endl; // prints out garbage

         // Send double to client
         double dVal2 = 6.28;
         char const * p_dVal2 = reinterpret_cast<char const *>(&dVal2);
         boost::asio::write(socket, boost::asio::buffer(p_dVal2, sizeof(double)));
      
   
   catch (std::exception & e)
   
      std::cerr << e.what() << std::endl;
   

   return 0;

Java 客户端代码:

import java.io.*;
import java.net.*;

public class Client

    final static String HOST = "localhost";
    final static int    PORT = 19876;

    public static void main(String[] args) throws IOException
    
        Socket socket = new Socket(HOST, PORT);

        // Send string to server
        PrintWriter pos = new PrintWriter(socket.getOutputStream(), true);
        pos.println("Client string to send to server");

        // Receive string from server
        BufferedReader bis =
            new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println(bis.readLine());

        // Send double value to server
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeDouble(3.14);

        // Receive double from server
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        System.out.println(dis.readDouble()); // prints out garbage

        socket.close();
        pos.close();
        bis.close();
        dos.close();
        dis.close();
    

提前非常感谢您!!!

亚伦

【问题讨论】:

【参考方案1】:

您需要使用lexical_cast,而不是reinterpret_cast

使用reinterpret_cast,您是在告诉编译器将double* 位模式逐字解释为const char* 位模式。相反,您的演员应该使用 ascii 字符创建一个新结构,该结构表示 ascii 位模式中的数字。

此外,您应该确保您管理的是字节序。您应该在客户端和服务器上正确转换网络字节序。更多信息请参见this answer。

【讨论】:

以上是关于在 Boost ASIO 服务器和 Java 客户端之间通过 TCP 发送双精度的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost-asio 的 C++ 和 Python 程序之间的客户端服务器

Boost asio——读写同时进行

boost::asio 完全断开连接

boost :: asio :: ip :: tcp :: iostream,首先启动客户端并等待服务器?

c++ - Boost ASIO 网络服务器/客户端

Boost::asio - 如何中断阻塞的 tcp 服务器线程?