ASIO服务器和Java客户端

ASIO服务器和Java客户端

本文介绍了在Boost ASIO服务器和Java客户端之间通过TCP发送双打的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

下面是显示我的基本设置(带有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();
    }
}

非常感谢您!

亚伦

解决方案

您需要使用 lexical_cast ,而不是reinterpret_cast.

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

此外,您还应该确保自己在管理端倪.您应该在客户端和服务器上都正确地与网络端之间进行转换.有关其他信息,请参见此答案./p>

I am trying to set up a simple Boost ASIO server with a single Java client.

I am able to send and successfully receive strings between the two. However, when I try to send double values, only garbage comes out on the other end.

Below is stand alone code that shows my basic setup (with a C++ Boost ASIO server and a Java client). When they are run, they do the following four sequential tasks:

  1. The client sends a string to the server, which is successfully received and printed out.
  2. The server sends a string to the client, which is successfully received and printed out.
  3. The client sends a double value to the server, which is received but does NOT print outcorrectly.
  4. The server sends a double value to the client, which is received but does NOT print outcorrectly.

Does anyone know what I am doing wrong? I am admittedly very new to networking (and Java). I have been through the Boost ASIO documentation and examples but to know avail.

C++ Boost ASIO server code:

#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 client code:

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();
    }
}

Thank you very much in advance!!!

Aaron

解决方案

You need to use a lexical_cast, not a reinterpret_cast.

With reinterpret_cast, you're telling the compiler to literally interpret the double* bit pattern as a const char* bit pattern. Instead, your cast should create a new structure with ascii chars that represent the number in an ascii bit pattern.

Also, you should ensure that you're managing endianess. You should properly convert to and from network endianess on both the client and server. See this answer for additional information.

这篇关于在Boost ASIO服务器和Java客户端之间通过TCP发送双打的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:48