我有一个用 Java 编写的客户端和一个用 C++ 编写的服务器。客户端在收到服务器的响应后,应该每 5 秒发送一条类似“MESSAGE|1|2|3|4|5”的消息。
开始连接:
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;
private BufferedReader br = null;
private Timer timer;
public void start()
{
int timerRate = 5;
try
{
int refreshRate = Integer.parseInt(appSingleton.getRefreshRateShared());
timerRate = refreshRate;
}
catch(NumberFormatException e)
{
LOGGER.addLogError("Error converting refresh rate: "+e);
}
try
{
// Create socket and streams
socket = new Socket(appSingleton.getIpAddressFullShared(), appSingleton.getIpPortShared());
input = new DataInputStream( socket.getInputStream());
output = new DataOutputStream( socket.getOutputStream());
// Start Timer thread
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(new Runnable()
{
@Override
public void run()
{
// Create new TCP connection if the map is not currently updating
if(isMapUpdating == false)
{
isMapUpdating = true;
communicateWithServer();
}
}
}, 0, timerRate, TimeUnit.SECONDS);
}
catch (UnknownHostException e)
{
cancelConnection();
}
catch (EOFException e)
{
cancelConnection();
}
catch (IOException e)
{
cancelConnection();
}
}
public void communicateWithServer()
{
// Create a message to the server
String messageToServer = makeMessageToServer();
String messageFromServer = connectToClient(messageToServer);
// Read the message and update panel on the main thread
SwingUtilities.invokeLater(() ->
{
messageReceived(messageFromServer);
});
}
public String connectToClient(String messageToServer)
{
String data = "";
// Message from the server that should terminate TCP connection
String terminator = "END_DATA";
try
{
//Send message to the server
output = new DataOutputStream( socket.getOutputStream());
output.writeBytes(messageToServer);
System.out.println("OUTPUT LENGTH: "+output.size());
//Read Response
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String s = "";
int value;
// Process the message from the server and add to the StringBuilder
while((value = br.read()) != -1)
{
// converts int to character
char c = (char)value;
sb.append(c);
if(sb.toString().contains(terminator))
{
break;
}
}
// Create the final string
data = sb.toString();
}
catch (IOException e)
{
cancelConnection();
data = "ERROR";
}
return data;
}
private void messageReceived(String message)
{
// Processing data from server and displaying values on Main Thread
// Map finished updating when data is processed
isMapUpdating = false;
}
服务器从客户端获取消息,将其转换为数组,然后进一步处理数据。第一条消息发送得很好。然而,在第二条消息时,服务器崩溃了。我检查了发送到服务器的内容,结果发现消息是这样的:
“消息|1|2|3|4|5”
“M”
“ESSAGE|1|2|3|4|5”
因此,服务器在收到第二条消息时崩溃,因为它无法将其拆分为数组。
当我检查 DataOutputStream 时,它总是显示正确的大小。
如果有人知道如何解决它,我们将不胜感激!
最佳答案
好吧,如果你要编写网络软件,双方都需要能够处理数据可能是碎片化的并一 block 一 block 地到达;您通常无法完全控制这一点。
不过,为了降低风险,请在写入输出流后刷新它:
output = new DataOutputStream( socket.getOutputStream());
output.writeBytes(messageToServer);
output.flush();
它告诉流将缓冲数据写入下一层。
关于Java 客户端向服务器发送部分消息,尽管显示为完整消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49222046/