我的 TCP 数据很少,但足以引起注意、以错误的顺序接收或完全丢失。
例如,我的客户端将发送 Log:joehot200;Password
,服务器将接收 ehot200;Password
我检查了TCP - received in wrong order和 TCP data occasionally received in wrong order and incomplete也没有帮助。他们似乎都没有提供足够的细节或没有解决问题的非答案。
我使用此代码在客户端和服务器上发送数据:
public void sendData(String data){ //Server code
try{
System.out.println("Sent " + data);
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
outToClient.writeBytes(data + "\n");
}catch (Exception e){
e.printStackTrace();
}
}
public void sendData(String data){ //Client code
try{
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(data + "\n");
}catch (Exception e){
}
}
这是正在发送/接收的数据类型:
Data: UID:1;Pitch:0.0
FROM SERVER: Name:1;joehot200
Data: Name:1;joehot200
FROM SERVER: Type:1;2
Data: Type:1;2
FROM SERVER: FlaBag:1;0
Data: FlaBag:1;0
FROM SERVER: Teall-104,442m:1;1
Data: Teall-104,442m:1;1
FROM SERVER: 6.572884235079,51.82797146606425,5670.44316581469,0
事实上,看看上面的数据,甚至是错误的!!我没有以 FlaBag 或 Teall 开头的数据包。
这里出了什么问题?
我正在从多个线程发送数据,但显然我是在同一线程上接收所有数据。
最佳答案
所以基本上问题是每个调用此函数的函数:
public void sendData(String data){ //Client code
try{
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(data + "\n");
}catch (Exception e){
}
}
在单独的上下文中调用它,因此它将创建线程本地 DataOutputStream,一旦线程离开 sendData 上下文,该 DataOutputStream 将被销毁,实际上多个客户端正在发送按顺序到达的多个 tcp 数据包,但客户端不同步。要解决此问题,您应该做的是在函数外部声明 DataOutputStream 并将方法设置为 synchronized 。这将防止多个线程同时执行同一个方法。最后你的代码应该看起来像这样:
public class Blaaa {
...
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
public synchronized void sendData(String data) {
outToServer.writeBytes(data + "\n");
}
}
这应该处理无序接收,但您的线程仍然可以无序调用 sedData 方法(尽管至少它不会交错)。您可能需要一些额外的逻辑来防止这种情况。
关于java - TCP 数据接收顺序错误/丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29142625/