0

我有一个应用程序必须通过 TCP 套接字将数据发送到另一个应用程序。这是从客户端到服务器的单向流。发送数据时,客户端必须重试/重新连接,并尝试确保在接收器/侦听器/服务器死亡/消失或断开连接时发送所有数据。我的代码如下:

public class TCPSocket implements Closeable {

    private static final int SIXTY_FOUR_KB = 65536;

    private final String ip;
    private final int port;
    private Socket socket;
    private BufferedOutputStream writer;

    public TCPSocket(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    public TCPSocket connect() throws ConnectException {
        try {
            socket = new Socket(ip, port);
            socket.setSendBufferSize(SIXTY_FOUR_KB);
            writer = new BufferedOutputStream(socket.getOutputStream(), SIXTY_FOUR_KB);
        } catch (Exception e) {
            throw new ConnectException(e.getMessage());
        }
        return this;
    }

    public void write(String message) throws InterruptedException {
        boolean succeeded = true;
        do {
            try {
                writer.write(message.getBytes(StandardCharsets.UTF_8));
                writer.write("\n".getBytes(StandardCharsets.UTF_8));
   
            } catch (Exception e) {
                System.out.println(e.getMessage());
                succeeded = false;
                // Exponential backoff to go here
                try {
                    System.out.println("Attempting reconnection");
                    tryClose();
                    connect();
                } catch (ConnectException connectException) {
                    System.out.println(connectException.getMessage());
                }
            }
        } while (!succeeded);
    }

    private void tryClose() {
        try {
            close();
        } catch (Exception ex) {
            System.out.println("Failed closing TCPSocket");
        }
    }


    @Override
    public void close() throws IOException {


        if (writer != null) {
            writer.flush();
            writer.close();
            writer = null;
        }

        if (socket != null && !socket.isClosed()) {
            socket.close();
            socket = null;
        }

    }
}

注意:使用 BufferedOutputStream 的原因是因为我正在发送小消息,而所有其他方法在现实世界的测试场景中无法获得相同的吞吐量。

这一切对我来说都按预期工作,但是我有几点。

  1. 这是正确的方法还是完全疯狂并会导致严重的问题?

  2. 在打开新连接之前尝试清理和关闭连接和编写器时,会引发以下错误,我无法关闭 bufferedOutputStream

    java.net.SocketException:对等方重置连接:套接字写入错误

    如果我socket.shutdownOutput();在尝试关闭输出流之前,那也会引发异常。清理和重新连接的正确方法是什么?

4

0 回答 0