отправка двойников по TCP между сервером Boost ASIO и клиентом Java

Я пытаюсь настроить простой сервер Boost ASIO с одним клиентом Java.

Я могу отправлять и успешно получать строки между ними. Однако, когда я пытаюсь отправить двойные значения, на другом конце выходит только мусор.

Ниже приведен автономный код, который показывает мою базовую настройку (с сервером C ++ Boost ASIO и клиентом Java). При запуске они выполняют следующие четыре последовательных задачи:

  1. Клиент отправляет на сервер строку, которая успешно принимается и распечатывается.
  2. Сервер отправляет клиенту строку, которая успешно принимается и распечатывается.
  3. Клиент отправляет на сервер двойное значение, которое получает, но НЕ распечатывает правильно.
  4. Сервер отправляет клиенту двойное значение, которое получает, но НЕ распечатывает правильно.

Кто-нибудь знает, что я делаю не так? По общему признанию, я очень новичок в сетях (и 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();
    }
}

Заранее большое спасибо!!!

Аарон


person Jammy    schedule 08.08.2013    source источник


Ответы (1)


Вам необходимо использовать lexical_cast, а не reinterpret_cast .

С reinterpret_cast вы говорите компилятору буквально интерпретировать double* битовый шаблон как const char* битовый шаблон. Вместо этого ваше приведение должно создать новую структуру с символами ascii, которые представляют число в битовом шаблоне ascii.

Кроме того, вы должны убедиться, что управляете порядком байтов. Вы должны правильно конвертировать в и из сетевого байта как на клиенте, так и на сервере. Дополнительную информацию см. В этом ответе.

person Homer6    schedule 08.08.2013