簡體   English   中英

使用線程處理多個Java TCP客戶端

[英]Handling multi Java TCP clients with Threads

我使用TCP服務器/客戶端的東西已有一段時間了。 在連接多個客戶端的多個用戶方面,我精通UDP編程。 我試圖在使用線程制作的TCP服務器上執行相同的操作,但是只要線程到達這段代碼

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();
    }
}

}

僅供參考,這並不陌生。 導致此錯誤的原因是,即使沒有要接收的數據包,服務器也開始接收數據包。 但是由於線程強迫它接收它,因此我在線程中產生了錯誤,並且不知道有任何其他方法可以解決此問題。 所以請幫忙。 提前致謝。

每個連接不需要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-使用ObjectInputStream監聽套接字

ObjectInputStream(socket.getInputStream()); 不起作用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM