【发布时间】:2014-07-30 09:08:49
【问题描述】:
我想创建一个可以与多个客户端连接的服务器,但是我总是得到'Socket Closed'异常或从输入流中读取NULL值,以前我认为这是由于以错误的方式关闭套接字连接引起的,所以我发布了这个topic,但现在看来这不是问题。
服务器方法
//here I use thread pool to solve concurrency issue
public static void main(String[] args) {
try{
ExecutorService service = Executors.newFixedThreadPool(4);
ServerSocket serverSocket = new ServerSocket();
while (true) {
//keep listening
Socket socket = serverSocket.accept();
service.execute(new HandlerThread(socket));
}
}catch(Exception ex){
ex.printStackTrace();
}
}
HandlerThread 类
public class HandlerThread extends Thread{
private Socket socket;
private BufferedReader in;
public HandlerThread(Socket socket) throws IOException {
this.socket = socket;
this.start();
}
public void run(){
try {
//Caches is a singleton class, which used to store the received data from client
Caches caches = Caches.getInstance();
//32 line
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String line = in.readLine();
//caches.list is an ArrayList
synchronized (caches.globalCaches) {
if (null != line) {
caches.globalCaches.add(line);
}
}
System.out.println(line);
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端模拟器
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
for(int i = 0 ; i < 40; i++){
Thread.sleep(2000);
test test1 = new test();
test1.start();
}
}
public static class test extends Thread{
public void run(){
try {
Socket socket = new Socket("localhost", 5050);
PrintStream out = new PrintStream(socket.getOutputStream());
out.println("Hello Server!");
out.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
异常和问题
在客户端模拟器之前启动服务器,客户端模拟器没有任何异常,但是在服务器端,并没有收到所有数据,从控制台打印信息中,我看到'null','Hello Server','java. net.SocketException: Socket is closed...',如下所示
Hello Server
null
null
Hello Server
java.net.SocketException: Socket is closed
Hello Server
at java.net.Socket.getInputStream(Socket.java:876)
at com.icubeidea.core.threads.HandlerThread.run(HandlerThread.java:32)
Hello Server
我研究了很长时间,仍然找不到到底是什么导致了这些异常和数据丢失的问题,还有可能导致服务器运行一段时间后出现内存泄漏问题的潜在风险?
【问题讨论】:
-
可能是因为您在线程上调用 start() 的方式。改用
service.execute(new HandlerThread(socket).start());并从HandlerThread构造函数中删除this.start()。 -
"尝试 service.execute(new HandlerThread(socket).start());" ——不啊啊啊啊!!!这是一个双重错误!幸运的是它甚至不会编译。
-
@user3811473 你的怀疑是正确的,但是解决方法是错误的,正如 Hanno 所说,它甚至不会被编译。
-
@Z.Neeson,是的,我意识到为时已晚,通常它会起作用,但由于线程被传递给执行器,它接受一个线程对象,然后不能在那里调用 start :) 我没有测试它,这就是为什么我没有把它写成答案:)
-
@user3811473 同意。如果没有执行器,建议不要从其构造函数中启动线程。
标签: java multithreading sockets