【问题标题】:Socket closed as soon as passed into new thread套接字在传递到新线程后立即关闭
【发布时间】:2016-08-06 17:52:22
【问题描述】:

我正在尝试创建一个多线程双工聊天服务器。在将代码移入线程之前,我让它工作正常,但现在每当线程尝试访问套接字时,我都会收到“SocketException:Socket is closed”。

我的老师和我想不通。 (老师对 Java 的了解甚至比我还少;他是 C 人)。貌似socket是打开的,但是一进入线程就关闭了。

我做错了什么?

客户端代码:

public class Client {
    public static void main(String[] args) throws IOException {
        String hostName = "localhost";
        int portNumber = 6969;
        try (
                Socket socket = new Socket(hostName, portNumber);
        ) {
            System.out.println("Chat connected");
            //Sender
            if (!socket.isClosed())
                new Thread(new Sender(socket)).start();
            //Receiver
            if (!socket.isClosed())
                new Thread(new Receiver(socket)).start();
        } catch (SocketException e) {
            System.out.println("Connection terminated unexpectedly");
        }
    }
}

服务器代码:

public class Server {
    public static void main(String[] args) throws IOException {
        int portNumber = 6969;
        try (
                ServerSocket serverSocket = new ServerSocket(portNumber);
                Socket clientSocket = serverSocket.accept();
        ) {
            //Receiver
            if (!clientSocket.isClosed())
                new Thread(new Receiver(clientSocket)).start();
            //Sender
            if (!clientSocket.isClosed())
                new Thread(new Sender(clientSocket)).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

接收线程代码:

class Receiver implements Runnable {

    private Socket socket;

    Receiver(Socket s) throws IOException {
        socket = s;
    }

    @Override
    public void run() {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
            String received;
            do {
                received = in.readLine();
                if (received == null) break;
                System.out.println("Them: " + received);
            } while (!received.contains("/dropmic"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

发件人线程代码:

class Sender implements Runnable {
    private Socket socket;

    Sender(Socket s) throws IOException {
        socket = s;
    }

    @Override
    public void run() {
        try (PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {
            String sent;
            do {
                System.out.print("You: ");
                sent = stdIn.readLine();
                if (sent == null) break;
                out.println(sent);
            } while (!sent.contains("/dropmic"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务器输出:

java.net.SocketException: Socket is closed
    at java.net.Socket.getOutputStream(Socket.java:943)
    at Sender.run(Sender.java:16)
    at java.lang.Thread.run(Thread.java:745)
java.net.SocketException: Socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at Receiver.run(Receiver.java:19)
    at java.lang.Thread.run(Thread.java:745)

Process finished with exit code 0

客户端输出(仍在运行):

Chat connected
You: java.net.SocketException: Socket is closed
    at java.net.Socket.getInputStream(Socket.java:903)
    at Receiver.run(Receiver.java:16)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • 你能发布你的输出吗?
  • 是的,已编辑原帖

标签: java multithreading sockets


【解决方案1】:

您正在使用 try-with-resources 语句,并将套接字作为资源。但是,当您创建新线程时,此 try-with-resources 会到达其代码的末尾并关闭套接字。将您的套接字放在实际的 try 语句中并手动关闭它们以解决此问题。

【讨论】:

  • 我们刚刚花了一个多星期的时间试图找到这个解决方案。你是我的英雄。
猜你喜欢
  • 2019-12-11
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 2022-07-27
  • 2017-09-10
  • 2014-06-14
  • 2010-11-23
相关资源
最近更新 更多