I'm trying to send commands from my client side, implemented with Java, to the server side, implemented using C++, through TCP connection. The server-side code is given and tested, so I'm fairly certain that the parsing of the command is not the problem. But when I try to send String commands from the Java side, the server side receives multiple packages sometimes so it does not get parsed correctly. Since the server only executes a command when it ends with a new line symbol, the first part of the command gets discarded and an unknown message error is thrown. I'm using the DataOutputStream for the Java side, and using DataOutputStream.writeBytes(String s) to write my command, and using a BufferedReader to read the message returned by the server.
I'm able to test the server by using telnet to connect to the server without launching Java side code. From telnet, I can successfully send multiple commands and they get parsed correctly. However, when I try to send commands from Java, they get broken up into pieces. The first command is always fine, which is always "add_server 3\n", and the second command, which is "dec_dimmer\n" gets chopped up into "d" and "ec_dimmer\n" and all the subsequent commands in a similar fashion.
Here's how the send command part is implemented:
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;
In addition, the exact same client has been implemented in c++ before and is working perfectly fine. The following function is the send command function from the c++ version of the client:
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;
}