问题
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:
- The client sends a string to the server, which is successfully received and printed out.
- The server sends a string to the client, which is successfully received and printed out.
- The client sends a double value to the server, which is received but does NOT print out correctly.
- The server sends a double value to the client, which is received but does NOT print out correctly.
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
回答1:
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.
来源:https://stackoverflow.com/questions/18131653/sending-doubles-via-tcp-between-boost-asio-server-and-java-client