使用线程处理多Java TCP客户端

时间:2016-01-21 15:36:26

标签: java tcp server client

我一直在使用TCP服务器/客户端的东西。在连接多个客户端的多个用户时,我非常擅长UDP编程。我尝试在使用Threads的TCP服务器上做同样的事情,但是每当Thread获得这段代码时

String reader = (String)in.readObject();

生成错误并且线程停止执行代码但线程仍然运行程序使其保持活动状态。 无论如何这里是完整的源代码:

public class TestServer implements Runnable {

private Thread run, streams, connect, receive, send;

private ServerSocket socket;
private Socket conn;
private ObjectInputStream in;
private ObjectOutputStream out;

private boolean running, incomingMessage = false;
private int port;

public TestServer(int port) throws IOException {

    this.port = port;

    socket = new ServerSocket(port);

    console("Server stated on : " + InetAddress.getLocalHost() + " : " + port);

    run = new Thread(this, "Run");
    run.start();

}

public void run() {

    running = true;
    connect();
    receive();
}

private void connect() {

    connect = new Thread("Connect") {

        public void run() {

            while(running) {

                try {
                    conn = socket.accept();
                } catch (IOException e) {

                    e.printStackTrace();
                }

                console("You are now connected" + conn.getInetAddress().toString() + " : " + conn.getPort());

                try {
                    setupStreams();
                } catch (IOException e) {

                    e.printStackTrace();
                }

            }


        }

    }; connect.start();

}

private void setupStreams() throws IOException {

    streams = new Thread("Streams") {

        public void run() {

            try {

                console("Setting up Streams");

                out = new ObjectOutputStream(conn.getOutputStream());
                out.flush();

                in = new ObjectInputStream(conn.getInputStream());

                console("Streams are now setup");

                incomingMessage = true;
                receive.start();

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

    }; streams.start();



}

private void receive() {

    receive = new Thread("Receive") {

        public void run() {

            while(incomingMessage) {

                String message = "";

                try {

                    message = (String) in.readObject();
                    //This is the only flaw the program

                } catch (ClassNotFoundException | IOException e) {

                    e.printStackTrace();
                }

                console("Client : " + message);
            }
        }

    };
}

private void console(String message) {
    System.out.println(message);
}

public static void main(String[] args) {
    try {
        new TestServer(1234);
    } catch (IOException e) {

        e.printStackTrace();
    }
}

}

我不是新手。导致该错误是因为即使没有要接收的数据包,服务器也会开始接收数据包。但是因为线程强制它接收它,我在线程中生成错误,并且不知道任何其他方法来对付它。所以请帮忙。在此先感谢。

1 个答案:

答案 0 :(得分:0)

每个连接不需要2个线程。只需一个线程即可。接受连接后,将其传递给工作线程以开始读取。这可以在工作线程中的while循环中完成。

即使可以读取套接字的输入流,ObjectInputStream()类也更敏感。如果有任何错误,则其状态已损坏且无法使用。

    while (true) {
        try {
            Object input = in.readObject();
            message = (String) input;
        } catch (IOException e) {
            e.printStackTrace();
            break; //unrecoverable
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            break; //unrecoverable
        }

        console("Client : " + message);
    }

使用特定的消息协议而不是发送序列化的Java对象是一种更好的设计。例如,如果您像示例一样发送字符串,则可以使用InputStreamReader将字节更容易地转换为字符,并减少错误处理。

这些资源对您有所帮助:

https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later

Java - Listening to a socket with ObjectInputStream

ObjectInputStream(socket.getInputStream()); does not work