java - 从 Java 客户端发送的命令在被 C++ 服务器端接收之前被分割成多个部分
问题描述
我正在尝试通过 TCP 连接从我的客户端(使用 Java 实现)发送命令到使用 C++ 实现的服务器端。服务器端代码已经给出并经过测试,所以我相当肯定命令的解析不是问题。但是当我尝试从 Java 端发送字符串命令时,服务器端有时会收到多个包,因此无法正确解析。由于服务器仅在命令以换行符结尾时才执行命令,因此命令的第一部分被丢弃并引发未知消息错误。我在 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++版本客户端的发送命令函数:
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;
}
解决方案
推荐阅读
- java - 从对角二维数组中获取元素
- postgresql - postgres 中的 BIGSERIAL 线程安全吗?
- python - 如何在 Python 处理中将变量设置为 = 宽度或高度?
- javascript - 尝试删除多于一行时的奇怪行为
- r - R删除特定字符后跟街道地址中的数字
- python - 如何根据重复的 id 填充 NaN?
- python - 尝试从 python tornado 服务器将内容呈现为 html 时出错
- image - 如何提取图像元数据 Dart/Flutter
- ssl-certificate - java api从同一个pem文件中读取证书和CRL
- maven - 为什么即使我已经在 pom.xml 中包含了依赖项,我也会收到 NoClassDefFoundError?