【问题标题】:Java: Socket closing after try-catch blocksJava:在try-catch块后关闭套接字
【发布时间】:2015-07-14 19:03:58
【问题描述】:

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

服务器,这是我的一个类的构造函数。它分解为,我的 main 在不同的线程上有实际的服务器内容,(就像我以前的帖子一样)这是一个修复,以便 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)

【问题讨论】:

标签: java multithreading sockets


【解决方案1】:

因为您使用try 块的方括号创建socket,所以它会在退出块时自动关闭。相反,尝试在块本身内创建它,它不应该被关闭:

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 教程,了解更多关于为什么会出现当前行为的信息。

【讨论】:

  • 这对我不起作用。 try 块不会让我做 this.sock = new blank blank。我收到 IDE 错误,似乎它只允许我创建一个变量然后分配它而不是这样做,:( 糟透了,我知道为什么我要这样做,否则这将是最好的!
  • 我得到:“类型的非法开始=预期----
  • 非法开始类型 = 预期在我的 netbeans 8 IDE 上
  • 您确定您使用的语法与我的答案相同吗?能否上传错误截图?
  • 这里是 ss,抱歉我不知道有什么其他方法可以给你,也忽略我所有奇怪的额外代码 lol drive.google.com/file/d/0B2TiGzeynAl2QVF4Qk9FZWNuRzQ/…@DanielGibbs
【解决方案2】:

您正在使用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 (...)的resources子句之外初始化socket就不会被关闭

【讨论】:

  • @Dariuzs 摆脱大括号修复它:)
猜你喜欢
  • 2011-08-27
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
相关资源
最近更新 更多