我正在尝试一个客户端/服务器类型的聊天框(使用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)
答案 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 (...)
的资源条款之外初始化套接字,它就不会被关闭