线程是反社会的

时间:2011-02-10 07:49:26

标签: java multithreading sockets networking

所以我有两个线程 - 服务器线程和客户端线程。我可以让服务器写入,但它永远不会被客户端读取。以下是客户端,服务器以及服务器为处理客户端连接而生成的线程。

客户端 - 连接到套接字并尝试与服务器进行乒乓。客户希望服务器首先与它通信!

public class ClientMain {    
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("localhost", 14285);

        BufferedReader in = null;
        PrintWriter out = null;
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());
        } catch(IOException e) {
            Log.write("Error in client thread ");
            Log.write(e);
        }
        while(true) {
        System.out.println("About to read!! :-D");
            String fromServer = in.readLine();
            System.out.println("From server: " + fromServer);
            out.println("PONG");
        }
    }
}

服务器 - 这是服务器的启动方法。它产生一个用于观察serverSocket的线程,并根据需要生成客户端线程。是的,我意识到在类似的方法中定义类是一种不好的做法......如果难以阅读,我很抱歉。

public void start() {
    this.running = true;
    // probably could have done this better, but it gets the job done
    class Start implements Runnable {
        Server server;
        Start(Server server) { this.server = server; }
        public void run() {
            while(server.running) {
                try {
                    Socket socket = server.serverSocket.accept();
                    Log.write("Accepted socket");
                    new ClientThread(server,socket).start();
                } catch (IOException e) { e.printStackTrace(); }
            }
        }

    }
    Thread start = new Thread(new Start(this));
    start.start();
}

这是客户端线程 - 这也不是那么多。我从套接字中获取流,并写入一些数据,直到我不再拥有,然后从客户端获取一些数据。

        public void run() {
            Log.write("Running clientthread");
            BufferedReader in = null;
            PrintWriter out = null;
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out = new PrintWriter(socket.getOutputStream());

            } catch(IOException e) {
                running = false;
                Log.write("Error in client thread " + getName());
                Log.write(e);
            }
            while(running) {

                try {
                    String message = messageQueue.poll();
                    while(message != null) {
                        out.println(message);
                        Log.write("wrote message: " + message);
                        message = messageQueue.poll();
                    }
                    String input = in.readLine();
                    System.out.println("From client: " + input);
                    server.handle(username,input,this);
                }
                catch(IOException e) {
                    Log.write("Error in client thread " + getName() + " username=" + username);
                    Log.write(e);
                    break;
                }
            }
        }

现在这就是我在服务器端输出的内容:

Accepted socket
Running clientthread
wrote message: PING

这表明它正在获取连接并将消息写出来。 (为了清楚起见,当客户端线程被实例化时,PING会在messageQueue中填充,这样总是可以向客户端说话以开始对话。就像害羞线程的破冰船一样,是吗?)它也向我表明从客户端回来什么都没有,因为在in.readLine()

之后没有打印

此外,客户端上唯一的输出是它即将阅读的通知。那怎么能错过服务器写的东西呢?

感谢任何想法!

谢谢!

2 个答案:

答案 0 :(得分:3)

我在猜测,尝试添加:

out.flush();
out.close();

答案 1 :(得分:1)

每次要发送消息时添加out.flush();。 在完成之前不要关闭流。 完成流后,添加out.close();