Java多线程客户端/服务器-Java.net.SocketException:套接字已关闭
我必须使用Java的socket api编写多线程客户端和服务器。客户端和服务器都是多线程的,因此服务器可以处理多个连接,客户端可以测试服务器处理连接的能力 我的代码在这里: 我有一些问题,可能是相关的。一个,偶尔一个客户端线程会抛出Java多线程客户端/服务器-Java.net.SocketException:套接字已关闭,java,multithreading,sockets,Java,Multithreading,Sockets,我必须使用Java的socket api编写多线程客户端和服务器。客户端和服务器都是多线程的,因此服务器可以处理多个连接,客户端可以测试服务器处理连接的能力 我的代码在这里: 我有一些问题,可能是相关的。一个,偶尔一个客户端线程会抛出 java.net.SocketException: Socket closed at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStre
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at ClientThread.run(ClientThread.java:45)
at java.lang.Thread.run(Thread.java:680)
从它的位置来看,这意味着服务器在客户端完成读取之前正在关闭它的套接字。我怎样才能防止这种情况
此外,即使计算抛出
套接字关闭
异常的线程数,似乎并非所有服务器线程都在发送其输出。例如,30个服务器线程中有23个将发送其输出,但只有22个客户端线程将接收任何内容。通信显然在某处丢失了,我如何防止这种情况 您在ClientThread中的问题是:
private static Socket socket = null;
这意味着所有线程都在为ClientThread的所有实例共享同一个套接字实例。这意味着您的套接字将与会话状态不同步。您的对话是:
客户国:
sudo cat /etc/passwd
例如,捕获您的密码哈希。我认为你只是在学习,但我觉得你应该警惕你正在做的事情,以确保安全
另一件事是,只有当会话按预期进行时,服务器才会关闭套接字。您真的应该将close()调用移到try块上的finally块中。否则,如果客户端过早地关闭其套接字(这种情况会发生),那么服务器将泄漏套接字,并最终耗尽操作系统中的套接字
public void run() {
try {
} catch( SomeException ex ) {
logger.error( "Something bad happened", ex );
} finally {
out.close(); <<<< not a bad idea to try {} finally {} these statements too.
in.close(); <<<< not a bad idea to try {} finally {} these statements too.
socket.close();
}
}
public void run(){
试一试{
}捕获(某些例外){
logger.error(“发生了不好的事情”,例如);
}最后{
out.close();乍一看,我会提出以下问题:(1)您是否在服务器端刷新输出流(以确保没有数据等待写入),(2)在ClientThread.java
的第55-57行,我认为您不需要在关闭套接字的同时关闭流。请尝试不要这样做(在客户端和服务器端)并查看发生了什么。最后(3)查看JavaDoc中的close()
方法,看看这里是否有什么可以说明发生了什么:关于过早关闭。是的,我正在调用flush()每次任何一方发送数据时。但是,您使用最后一个参数将PrintWriter设置为autoflush,因此它已经可以为您执行此操作。不需要flush(),因为在auto flush中设置的PrintWriter将在每次打印*()后调用flush()方法调用。谢谢!这很有道理,我没有把静态修饰符放在那里,所以我对它视而不见。我已经用我的头敲了好几天了。