Java C/S端程序,Socket多线程问题

青春没有彩排丶 2017-05-26 05:04:40
写了一个socket服务器监听程序,点击"启动服务"按钮,之后程序就进入了阻塞状态,其它按钮都无效了
该如何解决啊,新手求赐教
    public void buildGUI() {
this.setTitle("监听服务器");
this.setSize(500, 500);
this.setLocationRelativeTo(null);
Container container = this.getContentPane();
container.setLayout(new BorderLayout());
JScrollPane centerPane = new JScrollPane();
dataArea = new JTextArea();
dataArea.setFont(new Font("宋体",Font.BOLD,15));
centerPane.setViewportView(dataArea);
container.add(centerPane,BorderLayout.CENTER);
dataArea.setEditable(false);
JPanel bottomPanel = new JPanel();
startBtn = new JButton("启动服务");
resetBtn = new JButton("清空数据区域");
bottomPanel.add(startBtn);
bottomPanel.add(resetBtn);
container.add(bottomPanel, BorderLayout.SOUTH);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
startBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
if(startBtn.getText() == "启动服务") {
try {
serverSocket = new ServerSocket(9997);
} catch (IOException e1) {
e1.printStackTrace();
}
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SZIE);
service();
dataArea.append("服务器监听已启动\n");
startBtn.setText("停止服务");
}else {
startBtn.setText("启动服务");
try {
serverSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
dataArea.append("服务器关闭!\n");
}
}
});
resetBtn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
dataArea.setText(null);
}
});

}

public void service(){
while(true) {
try {
socket = serverSocket.accept();
executorService.execute(new Runnable() {

private BufferedReader getReader(Socket socket) throws IOException{
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}

@Override
public void run() {
BufferedReader br = null;
try {
System.out.println("建立连接" + socket.getInetAddress() + ":" + socket.getPort());
dataArea.append("建立连接" + socket.getInetAddress() + ":" + socket.getPort());
br = getReader(socket);
String data = null;
if((data = br.readLine()) != null) {
//dealData(data);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(socket != null) {
socket.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
...全文
343 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 5 楼 a350062174 的回复:
没问题. 上面只是解决阻塞的方法. 你简单改下就可以保证只有一个线程.

           Thread cu = null;
           @Override
            public void actionPerformed(ActionEvent e) {
                if(startBtn.getText() == "启动服务") {
                    try {
                        serverSocket = new ServerSocket(9997);
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SZIE);
                    
                    cu = new Thread(){
				public void run() {
					service();
				}
			}
                    dataArea.append("服务器监听已启动\n");
                    startBtn.setText("停止服务");
                }else {
                    startBtn.setText("启动服务");
                    try {
                        cu.interrupt();//    停止线程
                        serverSocket.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    dataArea.append("服务器关闭!\n");
                }
            }

按照您说的确实解决了,但是点击"停止服务"红色部分的代码还是有问题,报异常 java.net.SocketException: Socket is closed at java.net.ServerSocket.accept(Unknown Source) 显示意思是accept()方法还在接受数据,但是socket已经关闭了
a350062174 2017-05-27
  • 打赏
  • 举报
回复
没问题. 上面只是解决阻塞的方法. 你简单改下就可以保证只有一个线程.

           Thread cu = null;
           @Override
            public void actionPerformed(ActionEvent e) {
                if(startBtn.getText() == "启动服务") {
                    try {
                        serverSocket = new ServerSocket(9997);
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SZIE);
                    
                    cu = new Thread(){
				public void run() {
					service();
				}
			}
                    dataArea.append("服务器监听已启动\n");
                    startBtn.setText("停止服务");
                }else {
                    startBtn.setText("启动服务");
                    try {
                        cu.interrupt();//    停止线程
                        serverSocket.close();
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                    dataArea.append("服务器关闭!\n");
                }
            }

  • 打赏
  • 举报
回复
引用 3 楼 a350062174 的回复:
应该是 方法service 导致主线程堵塞. executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SZIE); service(); dataArea.append("服务器监听已启动\n"); 将 service(); 放到一个新的线程中调用试试: new Thread( new Runnable(){ public void run() { service(); } } ).start(); dataArea.append("服务器监听已启动\n");
new Thread()的匿名内部类方法是不是不太好,会开启很多线程操作吧
110成成 2017-05-27
  • 打赏
  • 举报
回复
while(true) 这里 不要一直true,设置一个布尔值,默认为true 当线程终止的时候,将改标志位设置为false,然后关闭socket 线程建议不要强制终止,要用条件让它退出。
  • 打赏
  • 举报
回复
upupupup
a350062174 2017-05-26
  • 打赏
  • 举报
回复
应该是 方法service 导致主线程堵塞. executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SZIE); service(); dataArea.append("服务器监听已启动\n"); 将 service(); 放到一个新的线程中调用试试: new Thread( new Runnable(){ public void run() { service(); } } ).start(); dataArea.append("服务器监听已启动\n");
110成成 2017-05-26
  • 打赏
  • 举报
回复
代码我简单看了下,首先server进入阻塞是对的,等待client发送数据 第二个就是你看下你的阻塞是不是在主线程里也就是ui线程 如果是这样的话,你的主线程不全都阻塞了,界面肯定是无相应的 应该把这个都放在子线程中去处理,有什么显示就通知主线程。
  • 打赏
  • 举报
回复
upupup

51,412

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧