我正在尝试通过TCP连接从使用Java实现的客户端向使用C ++实现的服务器端发送命令。服务器端代码已给出并经过测试,因此我可以肯定地说,命令的解析不是问题。但是,当我尝试从Java端发送String命令时,服务器端有时会收到多个包,因此无法正确解析。由于服务器仅在命令以换行符结尾时才执行命令,因此该命令的第一部分将被丢弃,并引发未知消息错误。 我正在使用Java端的DataOutputStream,并使用DataOutputStream.writeBytes(String s)编写命令,并使用BufferedReader读取服务器返回的消息。
我可以通过使用telnet连接到服务器来测试服务器,而无需启动Java辅助代码。从telnet,我可以成功发送多个命令,并且可以正确解析它们。但是,当我尝试从Java发送命令时,它们会分成几部分。第一个命令始终是正确的,总是“ add_server 3 \ n”,第二个命令是“ dec_dimmer \ n”,分成类似的“ d”和“ ec_dimmer \ n”,所有后续命令都类似时尚。
以下是发送命令部分的实现方式:
DataOutputStream outToServer = null;
try {
outToServer = new DataOutputStream(mClientSocket.getOutputStream());
} catch(IOException e) {
e.printStackTrace();
}
try {
String cmd = command + '\n';
if(mDebug) {
System.out.println("Sending Command: " + cmd);
}
outToServer.writeBytes(cmd);
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader inFromServer = null;
try {
inFromServer = new BufferedReader(new InputStreamReader(mClientSocket.getInputStream()));
} catch(IOException e) {
e.printStackTrace();
}
String jsonOutput = null;
try {
jsonOutput = inFromServer.readLine();
} catch(IOException e) {
e.printStackTrace();
}
if(mDebug) {
System.out.println("FROM SERVER: " + jsonOutput);
}
return jsonOutput;
此外,以前完全相同的客户端已经在c ++中实现,并且可以正常工作。以下功能是客户端c ++版本的send命令功能:
std::string SwimClient::sendCommand(const char* command) {
if (!socket.is_open()) {
throw std::runtime_error("socket is closed");
}
boost::system::error_code ignored_error;
cout << "sending command = " << command << endl;
boost::asio::write(socket, boost::asio::buffer(command, strlen(command)),
boost::asio::transfer_all(), ignored_error);
vector<char> buffer(128);
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buffer), error);
if (error)
throw boost::system::system_error(error);
string reply(buffer.data(), len);
if (reply.compare(0, 6, "error:") == 0) {
// trim strings
size_t last = reply.length() - 1;
while (isspace(reply.at(last))) {
reply.erase(last--);
}
string cmd(command);
last = cmd.length() - 1;
while (isspace(cmd.at(last))) {
cmd.erase(last--);
}
throw std::logic_error(reply + "(cmd " + cmd + ')');
}
return reply;
}