簡體   English   中英

Java多客戶端服務器不接收來自客戶端的消息?

[英]Java multi-client server doesn't receive message from client?

我設法設置了一個服務器,它將接受和管理多個套接字客戶端。 但是現在當我嘗試發送消息時,服務器只是沒有收到任何消息,但我確實刷新了消息。

這是管理客戶端的方法:

public void run() {

    while(true) {
        for (Client c : this.clients) {
            try {
                if (c.getStream().read() != -1) {
                    if (c.getInputStream() != null) {
                        System.out.println("He sent message");
                        c.sendMessage("hey client");
                    }
                }
            } catch (IOException e) {
                c.destruct();
                this.clients.remove(c); break;
            }
        }

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

客戶名單:

public ArrayList<Client> clients = new ArrayList<Client>(); // client list

和客戶對象:

public class Client {

    private Socket socket;
    private int clientId;
    private BufferedReader inStream;
    private PrintWriter outStream;
    private boolean socketAlive = true;

    public Client(Socket sock) {
        this.socket = sock;
    }

    public void setup() {
        setInputOutputStream();
        System.out.println("New connection: " + this.getIpAddress());
        this.sendMessage("Successfully connected!");
    }

    public BufferedReader getStream() {
        return this.inStream;
    }

    public String getInputStream() {
        String toReturn = "";
        try {
            toReturn = this.inStream.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return toReturn;
    }

    public void destruct() {
        try {
            this.inStream.close();
            this.inStream = null;
            this.outStream.close();
            this.outStream = null;
            System.out.println("Client destruct: " + this.socket.getLocalSocketAddress());
            this.socket.close();
            this.socket = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Socket getConnection() {
        return this.socket;
    }

    private void setInputOutputStream() {
        try {
            inStream = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); 
            outStream = new PrintWriter(this.socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(String s) {
        this.outStream.println(s);
        this.outStream.flush();
    }

    public String getIpAddress() {
        return this.socket.getRemoteSocketAddress().toString();
    }
}

和客戶端(發件人):

public static void main(String[] args) {
    try {
        System.out.println("Client started");
        Socket sock = new Socket("localhost", 43594);
        Scanner scanner = new Scanner(System.in);
        String input;
        PrintWriter out = new PrintWriter(sock.getOutputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));

        while (true) {
            input = scanner.nextLine();

            if (input != null) {
                out.print(input);
                out.flush();
            }
        }
    } catch (IOException e) {
        System.out.println("Client error");
    }

}

為什么我的服務器沒有收到任何東西

一樣東西:

如果我發送消息+斷開連接,這就是服務器將記錄的內容(看起來它只在斷開連接時發送消息或者其他東西,不,它只在它上面輸入if塊):

Server is successfully running on port 43594
New connection: /127.0.0.1:57102
He sent message
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at Client.getInputStream(Client.java:32)
    at ClientHandler.run(ClientHandler.java:21)
Client destruct: 0.0.0.0/0.0.0.0:43594

我做錯了什么? 我該如何解決這個問題

服務器(主類)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;

public class Server {

    private int port = 43594;

    public void listen() {
        System.out.println("Trying to listen...");
        try {
            final ServerSocket server = new ServerSocket(port);
            // Create new thread to handle clients I/O
            ClientHandler handler = new ClientHandler(server);
            // START it
            handler.start();
            System.out.println("Server is successfully running on port " + port);
            while (true) {
                // New connection found create a new Client object
                Client cl = new Client(server.accept());
                cl.setup();
                // add it to clietns list in the I/O handler
                handler.clients.add(cl);
            }           
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        // start up
        System.out.println("Starting up..");

        // server instance
        final Server server = new Server();

        // create a new thread for server
        new Thread(new Runnable() {
            @Override
            public void run() {
                // listen for new connections
                server.listen();
            }
        }).start();
    }
}

客戶端正在發送數據,服務器正在讀取。

我認為問題出在Client.getInputStream中

this.inStream.readLine(),它讀取一行文本。 從文檔:“讀取一行文本。一行被認為是由任何一個換行符('\\ n'),一個回車符('\\ r')或一個回車符后跟一個換行符終止“。

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

如果你改用read,也許它會起作用。 只需使用一種協議,例如使用消息的長度發送前1或2個字節。 或者您可以從客戶端發送'\\ n'。

順便說一下,在客戶端發送和斷開連接時服務器異常的原因可能是由於TCP事實。 客戶端關閉了連接,它可能從服務器收到TCP ACK。 然后,客戶端中的TCP發送RESET段。 雖然不太確定。 服務器位於this.inStream.readLine(),然后它收到一個異常。 你沒有收到“同行關閉的連接”嗎?

我不知道為什么,但我需要使用out.println(input) out.flush()而不是.print().write()

我沒有解釋為什么我需要這樣做。 但它奏效了。

我認為問題來自於你有一個客戶列表,並試圖用它來管理它們。 我查了java.net.SocketException: Connection reset ,發現這個問題: 是什么導致我的java.net.SocketException:連接重置?

這個問題的答案是:

在您的情況下,似乎連接已由連接的服務器端關閉。 這可能是您發送的請求或最終問題的問題。

這讓我覺得你每次都沒有與客戶建立聯系。 您存儲它,然后丟失它,因此不會發送消息。 要處理更多客戶端,您可能更願意擁有IP列表而不是客戶端,然后在要發送消息時進行連接。 您無法存儲Socket連接。 它必須是活躍的。 Java(JVM)擁有它自己的“垃圾收集”系統,它只會殺死它。

暫無
暫無

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

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