Java 套接字丢失数据:BufferedReader

sie*_*ema 1 java sockets tcp bufferedreader java-io

我在 Java 中遇到以下问题:我正在开发和应用程序使用java.net.Socket. 它看起来像这样:有一个服务器,它有一个线程,它接受并添加新客户端,另一个线程从套接字读取数据并用它做“某事”。旁边是客户。客户端具有数据读取器线程以及单独的线程。我发送的数据很简单:

socket.getOutputStream().write((content+"\n").getBytes());
Run Code Online (Sandbox Code Playgroud)

在客户端并在服务器上读取它,例如:

try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String received;
    while(true) {
        try {
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            received = reader.readLine();
            if(received == null) {
                break;
            }
            System.out.println("SERVER " + received);
            increaseReceivedCounter(1);
        } catch(SocketException e) {
            break;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    System.out.println("SERVER RECEIVED "+ getReceivedCounter() + " MESSAGES!");
}
Run Code Online (Sandbox Code Playgroud)

现在我只是设置客户端发送一些这样的消息:

try {
    int n = 1000;
    System.out.println("sending "+ n +" messages to " + client);
    for(int i=0 ; i<n ; ++i) {
        socket.getOutputStream().write((content+"\n").getBytes());
    }
    System.out.println("done sending " + n + " messages");
} catch (IOException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

问题是并非所有消息都传输到服务器。我一直在为此寻找一些解决方案,但未能实现 100% 的可靠性。甚至有可能吗?我也试过用read而不是,readLine但结果是一样的:有时甚至 90% 的数据丢失。我认为,当服务器正在接收的数据它忽略传入数据包和他们只是失去了。

编辑

Socket初始化:

serverSocket = new ServerSocket(Server.PORT);//PORT = 9876, whatever
Run Code Online (Sandbox Code Playgroud)

对于服务器端的数据读取器:

socket = serverSocket.accept();
Run Code Online (Sandbox Code Playgroud)

在客户端:

socket = new Socket("127.0.0.1", Server.PORT)
Run Code Online (Sandbox Code Playgroud)

use*_*421 5

不是“效率问题”。这是您代码中的错误。

问题是并非所有消息都传输到服务器。

但,问题是,你失去的数据服务器上。这是因为您一直在重新创建BufferedReaders. 您应该在套接字的生命周期内创建一次。

reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Run Code Online (Sandbox Code Playgroud)

删除此行。

就您拥有它的方式而言,每次先前BufferedReader已缓冲时,您都会丢失数据。

您还需要关闭套接字。