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

时间:2013-08-08 16:49:59

标签: java c++ boost client boost-asio

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

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

下面是独立代码,显示了我的基本设置(使用C ++ Boost ASIO服务器和Java客户端)。运行时,它们执行以下四个连续任务:

  1. 客户端向服务器发送一个字符串,该字符串已成功接收并打印出来。
  2. 服务器向客户端发送一个字符串,该字符串已成功接收并打印出来。
  3. 客户端向服务器发送一个double值,该值已收到但未打印出来 正确。
  4. 服务器向客户端发送一个double值,该值已收到但未打印出来 正确。
  5. 有谁知道我做错了什么?我无疑是网络(和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 个答案:

答案 0 :(得分:3)

您需要使用lexical_cast,而不是reinterpret_cast

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

此外,您应该确保管理结束。您应该在客户端和服务器上正确地转换为网络字节序列。有关其他信息,请参阅this answer