问题描述
我正在尝试使用单个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();
}
}
非常感谢您!
亚伦
您需要使用 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:
- 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 outcorrectly.
- 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发送双打的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!