【问题标题】:Simple chat client and chat server [duplicate]简单的聊天客户端和聊天服务器[重复]
【发布时间】:2016-05-29 20:20:48
【问题描述】:

我正在做一个简单的回声聊天和服务器,但 Connection 类中的方法 sendreceive 不适用于 ObjectInputStreamObjectOutputStream,但适用于 PrintWriterBufferedReader工作正常。

现在我正在尝试理解使用套接字的序列化,帮助我理解为什么这段代码不起作用:

客户

public class Client {
    private Connection connection;

    private String getServerAddress() {
        return "localhost";
    }

    private int getServerPort() {
        return 4444;
    }

    public void run() {
        BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));

        try {
            connection = new Connection(new Socket(getServerAddress(), getServerPort()));

            SocketThread socketThread = new SocketThread();
            socketThread.setDaemon(true);
            socketThread.start();

            while (true) {
                String text = bis.readLine();
                if (text.equalsIgnoreCase("exit"))
                    break;
                connection.send(text);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.run();
    }

    public class SocketThread extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    String message = connection.receive();
                    System.out.println(message);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

连接

public class Connection implements Closeable {
    private final Socket socket;
    private final ObjectInputStream in;
    private final ObjectOutputStream out;

    public Connection(Socket socket) throws Exception {
        this.socket = socket;
        this.in = new ObjectInputStream(socket.getInputStream());
        this.out = new ObjectOutputStream(socket.getOutputStream());
    }

    public void send(String message) throws Exception {
        out.writeObject(message);
    }

    public String receive() throws Exception {
        return (String) in.readObject();
    }

    @Override
    public void close() throws IOException {
        in.close();
        out.close();
        socket.close();
    }
}

服务器

public class Server {

    public static void main(String[] args) {
        int port = 4444;

        try (ServerSocket serverSocket = new ServerSocket(port)) {
            while (true) {
                Socket socket = serverSocket.accept();
                new Handler(socket).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static class Handler extends Thread {
        private Socket socket;

        public Handler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try (Connection connection = new Connection(socket)) {
                while (true) {
                    String message = connection.receive();

                    if (message.equals("exit"))
                        break;

                    System.out.println(message);

                    connection.send("Echo: " + message);
                }
            } catch (Exception e) {
            }
        }
    }
}

【问题讨论】:

  • 请发布您尝试过的内容以及收到的错误消息。
  • 我没有收到错误消息。我正在尝试在 ObjectInputStream 和 ObjectOutputStream 的“发送”和“接收”方法中使用同步块,但服务器不会将回显消息返回给客户端。但是使用 PrintWritter 和 BufferedReader 就可以了。
  • 尝试在您的Connection 中更改this.in = new ObjectInputStream(socket.getInputStream()); this.out = new ObjectOutputStream(socket.getOutputStream()); 的顺序。此外,您可能希望在每次发送某些内容时out.flush()(我不确定它是否会自动刷新,这可能会导致等待使用的缓冲区已满)。
  • 谢谢!现在一切正常。

标签: java multithreading sockets networking serialization


【解决方案1】:

这是因为ObjectInputStream 阻止尝试读取由ObjectOutputStream 在其构造函数中写入的流标头,并且您在输出流之前创建了两个输入流。您可以通过切换创建对象流的顺序来解决此问题:

    this.out = new ObjectOutputStream(socket.getOutputStream());
    this.in = new ObjectInputStream(socket.getInputStream());

javadoc for the ObjectOutputStream constructor 还指出,您可能希望在创建流后刷新流以确保发送标头。

【讨论】:

  • 感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多