java - TCP 数据接收顺序错误/丢失

标签 java sockets tcp

我的 TCP 数据很少,但足以引起注意、以错误的顺序接收或完全丢失。

例如,我的客户端将发送 Log:joehot200;Password,服务器将接收 ehot200;Password

我检查了TCP - received in wrong orderTCP 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/

相关文章:

java - 两种 JDBC 查询批处理方法中哪一种更快?

c - 原始套接字监听器

c - 我如何拒绝数据流过已建立的 TCP 连接,但套接字连接应保持有效状态。

tcp - JGroups 集群节点端口,如果 port_range 设置为 0 或默认值

java - 将 MutableClassToInstanceMap 与泛型一起使用时出现编译错误

java - 如何在其他北方的盒子布局中添加组件并使它们全部锚定在南方?

c++ - 组织 C++ 套接字服务器的最佳方式是什么?

Java Android 将数据发送到服务器应用程序永远不要使用 onPostExecute()

sockets - 为什么TCP套接字编程需要两个套接字(一个欢迎套接字和一个连接套接字)而UDP只需要一个?

java - Spring MVC 中 Devise (Ruby on Rails) 的等价物?