java Socket编程调用ServerSocket的close方法

来源:互联网 发布:安兔兔评测软件 编辑:程序博客网 时间:2024/05/17 00:00

做一个简单的聊天系统服务器

服务器中有一个输入端口的控件,两个JButton按钮“停止”和“运行”

点击“运行”按钮,启动服务器

点击“停止”按钮,调用ServerSocket的close方法,停止服务器。

上部分代码:

 

btn_ok.setText("运行");btn_ok.addActionListener(new java.awt.event.ActionListener() {public void actionPerformed(java.awt.event.ActionEvent e) {String strPort = port.getText().trim();try {serverSocket = new ServerSocket(Integer.parseInt(strPort));System.out.println("服务器已启动");btn_ok.setEnabled(false);} catch (NumberFormatException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}//消息分发new Thread(new MsgRunnable()).start();}


btn_quit.setText("停止");btn_quit.addMouseListener(new java.awt.event.MouseAdapter() {public void mouseClicked(java.awt.event.MouseEvent e) {try {if(serverSocket!=null){serverSocket.close();isRun = false;btn_ok.setEnabled(true);}else{JOptionPane.showMessageDialog(null, "服务还未启动,请启动服务再停止");}} catch (IOException e1) {e1.printStackTrace();}}});
class MsgRunnable implements Runnable{@Overridepublic void run() {while(true){try {                                if(!serverSocket.close()){Socket socket = serverSocket.accept();System.out.println("服务器正在监听");ClientPro cp = new ClientPro(socket);cp.start();addConnetion(socket, cp);                              }                            else{                                JOptionPane.showMessageDialog(null, "服务器已关闭");return;                              }} catch (IOException e1) {e1.printStackTrace();                              }  }}}

根据我的想法,点击“停止”时,serverSocket关闭,那么  分发线程中的if(!serverSocket.close())会执行判断,弹出服务器已关闭对话框,看起来好像挺符合代码的逻辑的。

但是实际运行时,却报Socket close异常。

于是各种调试,终于发现异常是分发线程的e1.printStackTrace();   

但为什么会报异常呢?

因为ServerSocket的accept方法是个当前线程阻塞方法,当它只有接受一个客户端链接时,才会往下执行,我们启动服务器后,进入serverSocket.accept方法

它就一直在等待客户端的链接,所以它虽然是个无限循环线程,但判定条件却是多余的(当然,前提是你没进入accept方法)。

这时突然我们的另一个线程将serverSocket关闭了,那么看下我们accept方法的源代码:

 public Socket accept() throws IOException {        if (isClosed())            throw new SocketException("Socket is closed");        if (!isBound())            throw new SocketException("Socket is not bound yet");        Socket s = new Socket((SocketImpl) null);        implAccept(s);        return s;    }


所以异常就产生了

这本来是个很简单的问题,但却困扰了好一会.........

原创粉丝点击