Java:在try-catch块之后关闭套接字

时间:2015-07-14 10:53:58

标签: java multithreading sockets

我正在尝试一个客户端/服务器类型的聊天框(使用GUI' s)。我不知道我在程序中使用的多线程的详细信息,因为我认为它不是问题的一部分(我希望不是),并且发布的代码量很大。无论如何,对于我的客户端和我的服务器,我在try块中创建了一个套接字和一些其他流类,并且有些原因使得套接字在catch块之后关闭。 PS我不会在任何可能早期结束的地方调用socket.close()方法

服务器,这是我的一个类的构造函数。它分解成,我的主要在不同的线程上有实际的服务器东西,(像我之前的帖子)它是一个修复,以便gui可以加载和运行服务器的东西,而无需等待另一个。无论如何,没有所有细节,这是我的代码

    public ChatAppProtocol(Socket sock) 
    {
        super("ChatAppServer");
        // this also has a clas var of Socket
        this.sock = sock;

        try (
            PrintWriter output = new PrintWriter(this.sock.getOutputStream(), true);
            BufferedReader input = new BufferedReader(new InputStreamReader(this.sock.getInputStream())) ;
        ) 
        {
           // first stream of a string is the username loging in from client 
           String name = input.readLine();
           // this returns false, so its not closed
           System.out.println("closed?: " + this.sock.isClosed());

        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
        // PROBLEM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // closed after the catch blocks  before methods even ends
        // p.s. i also plan on using the socket in another method but can't since it closes
        System.out.println("closed?: " +this.sock.isClosed());

    }

现在是我的客户

@FXML
private void login() 
{
        this.name = this.username.getText().trim();
        this.portnum = Integer.parseInt(this.port.getText());
        this.name = this.username.getText().trim();
        this.ipaddr = this.ip.getText().trim();

        try (t
            Socket socket = new Socket(this.ipaddr, this.portnum);
            PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
        ) 
        {
            this.sock = socket;
            output.println(this.name);
            // this returns false, not closed
            System.out.println("closed?: " +this.sock.isClosed());
        } 
        catch (UnknownHostException e) 
        {
            System.err.println("Problem at ip: " + this.ipaddr);
            System.exit(1);
        } 
         // PROBLEM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // returns true here, closes before methods end and i cant reuse it
        System.out.println("IS IT CLOSED!!!!!! " + this.sock.isClosed());
    }
}

那么,为什么这个不同的类,不同的文件,不同的项目套接字在try-catch块之后关闭了?无法在线找到答案,并且已经有一段时间了,我被困住了。在服务器端控制台上看到这个后我发现了这个问题

  java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:943)
at chatappserver.ChatAppProtocol.run(ChatAppProtocol.java:62)

2 个答案:

答案 0 :(得分:3)

由于您使用socket块的括号创建try,因此在退出块时会自动关闭。{p>相反,尝试在块本身内创建它并且它不应该被关闭:

try {
    this.sock = new Socket(this.ipaddr, this.portnum);
    PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
    output.println(this.name);
} catch (UnknownHostException e) {
    System.err.println("Problem at ip: " + this.ipaddr);
    System.exit(1);
}
// this.sock should still be open at this point.

阅读try-with-resources上的Java教程,了解有关您获取当前行为的原因的详细信息。

答案 1 :(得分:0)

您使用的是try-with-resources,大致等同于:

    try
    {
        this.sock = new Socket(this.ipaddr, this.portnum));
        output.println(this.name);
        // this returns false, not closed
        System.out.println("closed?: " +this.sock.isClosed());
    } 
    catch (UnknownHostException e) 
    {
        System.err.println("Problem at ip: " + this.ipaddr);
        System.exit(1);
    } finally {
        if (this.sock != null)
          this.sock.close();
    }

只需在try (...)的资源条款之外初始化套接字,它就不会被关闭