Java多客户端服务器不接收来自客户端的消息?

时间:2013-12-12 23:07:44

标签: java sockets networking stream

我成功设置了一台接受& amp;管理多个套接字客户端 但是现在当我尝试发送消息时,服务器只是没有收到任何消息,但我会刷新消息。

这是管理客户的方法:

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

3 个答案:

答案 0 :(得分:1)

客户端正在发送数据,服务器正在读取。

我认为问题出在Client.getInputStream

this.inStream.readLine(),它读取一行文字。 来自文档: “读取一行文字。一行被认为是由换行符('\ n'),回车符('\ r')或回车符后面的任何一行终止。”< / p>

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

如果你改用read,也许它会起作用。只需使用一种协议,例如使用消息的长度发送前1或2个字节。或者您可以从客户端发送'\ n'。

BTW,当您在客户端发送和断开连接时服务器中出现异常的原因可能是由于TCP事实。客户端关闭了连接,它可能从服务器收到TCP ACK。然后,客户端中的TCP发送RESET段。虽然不太确定。服务器位于this.inStream.readLine(),然后它收到一个异常。你没有收到“同行关闭的连接”吗?

答案 1 :(得分:1)

我不确定原因,但我需要使用out.println(input) out.flush()代替.print().write()

我没有解释为什么我需要这样做。但它确实有效。

答案 2 :(得分:0)

我认为问题来自于你有一个客户列表,并试图用它来管理它们。我查了java.net.SocketException: Connection reset,发现了这个问题:What's causing my java.net.SocketException: Connection reset?

这个问题的答案是:

  

在您的情况下,似乎连接已被关闭   服务器端的连接。这可能是请求的问题   你发送或发送问题。

这让我觉得你每次都没有与客户建立联系。您存储它,然后丢失它,因此不会发送消息。要处理更多客户端,您可能更愿意拥有IP列表而不是客户端,然后在要发送消息时进行连接。您无法存储Socket连接。它必须是活跃的。 Java(JVM)拥有它自己的“垃圾收集”系统,它只会杀死它。