Java多客户端服务器套接字获取错误

时间:2013-12-08 21:32:29

标签: java multithreading sockets networking

我尝试过制作一个简单的服务器来接受多个套接字&然后让他们输入并接收输出。

但似乎我做错了,因为我遇到了很多错误。 我试图做那么糟糕的方式吗?我怎样才能以更好的方式做到这一点?

我不明白为什么会出现这些错误:

Starting up..
Trying to listen...
Server is successfully running on port 43594
New connection: /127.0.0.1:60639
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:29)
    at ClientHandler.run(ClientHandler.java:19)
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:29)
    at ClientHandler.run(ClientHandler.java:19)
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:29)
    at ClientHandler.run(ClientHandler.java:19)
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:29)
    at ClientHandler.run(ClientHandler.java:19)
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:29)
    at ClientHandler.run(ClientHandler.java:19)
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:29)
    at ClientHandler.run(ClientHandler.java:19)

还有很多错误。它基本上一遍又一遍地循环相同的错误,但为什么呢?

我已经对代码进行了评论,因此您可以看到我尝试过的操作,并且可能会修复我这样做的方式。

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

public class ClientHandler extends Thread {

    private Thread handler;
    public ArrayList<Client> clients = new ArrayList<Client>(); // client list
    private ServerSocket server;

    public ClientHandler(ServerSocket s) {
        server = s;
    }

    public void run() {

        while(true) {
            // Loop every time through every client and see if he has wrote
            // anything to do server. I am 100% sure this is wrong, how can I do this
            // without using multithreads (thread per client)?
            for (Client c : this.clients) {
                if (c.getInputStream() != null) {
                    // found input, return a message.
                    c.sendMessage("hey client");
                }
            }
            try {
                // sleep for 100ms
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

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 String getInputStream() {
        String toReturn = "";
        try {
            toReturn = this.inStream.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return toReturn;
    }

    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 class TestClient {

    /**
     * @param args
     * @throws IOException 
     * @throws UnknownHostException 
     */
    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()));

            input = scanner.nextLine();

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

    }

}

为什么连接会一直重置?

2 个答案:

答案 0 :(得分:0)

客户端没有循环或延迟,因此只要发送数据就会立即退出。当程序退出时,操作系统总是关闭所有网络连接!

此外,我认为这不符合您的要求:System.out.println(reader.toString());。检查客户端的输出!

答案 1 :(得分:0)

您正在从服务器上编写您未在客户端阅读的内容。相反,客户只是在打印后退出。 'reader.toString()不做任何I / O.你需要调用一个read方法。