//惟一的问题是将客户端的dos窗口关闭(右上角的叉号),而不是通过程序中指定的关闭方式时,服务器端抛出异常.
不知哪位高手能给出解决办法//此程序与TCPClient.java配合使用,实现客户端与服务端会话(一人一句,不可错乱)
//bug: 当客户端异常关闭(直接关闭窗口)时,服务端抛出异常
import java.net.*;
import java.io.*;
public class TCPServer{
public static void main(String [] args) throws Exception{
   ServerSocket ss = new ServerSocket(6669);
   Socket s =null;
   BufferedReader br = new BufferedReader(new  InputStreamReader(System.in));
   DataInputStream dis=null;
   DataOutputStream dos=null;
   String attention ="你有话就说!!!....\n        注意:  若不愿说,那就输入\"exit\",一拍两散";
 while(true){
 s  = ss.accept();
 
   System.out.println(  "server: connect client.... ");    
   System.out.println("I said: "+attention);
   //向客户端写入数据,提示客户端联上了就别傻愣着,找点话说 
    dos = new DataOutputStream(s.getOutputStream());
    dos.writeUTF(attention);
   
    //获得客户端的输入流
    dis = new DataInputStream(s.getInputStream());
    String tempStr=null;
    String temp2=null;
    //判断如果客户端输入exit则退出循环,断开连接
    while(!(tempStr=dis.readUTF()).trim().equalsIgnoreCase("exit")){ 
                                            //从客户端读取数据并写到自已一端的屏上
             System.out.println( "client:  "+ tempStr);  
   
           //向客户端写入
           temp2=br.readLine();
           dos.writeUTF( temp2);
          System.out.println("I said: "+temp2);
           dos.flush(); 
           
           
         
    }
   if(dis!=null)
    dis.close();
    if(dos!=null)
    dos.close();
    dis=null;
    dos=null;
    if(s!=null)
   s.close();  
          }
                        


}
}
//此程序与TCPServer.java配合使用,实现客户端与服务端会话(一人一句,不可错乱)
import java.net.*;
import java.io.*;
public class TCPClient {
 public static void main(String [] args) throws Exception{
Socket s = new Socket("127.0.0.1",6669);//服务器端的端口,
BufferedReader br = new BufferedReader(new  InputStreamReader(System.in));
OutputStream os =s.getOutputStream ();
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis=  dis = new DataInputStream(s.getInputStream());
String tempStr=null;


//从服务器端读入一行数据,并在己方屏幕上显示  
         System.out.println("server:  "+dis.readUTF());
 
   while(!(tempStr=br.readLine()) .equals("exit")){//当客户端(此端)输入exit时跃出循环
//向服务端写入数据,此数据从屏幕读取
dos.writeUTF(tempStr);
System.out.println("I said :"+tempStr);
dos.flush();
//将服务器端的数据写到己方屏幕上
System.out.println("server: "+dis.readUTF());
   }
   //如果客户端(此端)输入了exit则向server端输出exit
   dos.writeUTF("exit");
           if(dis!=null)
    dis.close();
    if(dos!=null)
    dos.close();
    dis=null;
    dos=null;
    if(s!=null)
   s.close();
 }
 }

解决方案 »

  1.   

    看看我这个,//package QQClient;class TwoClientThread extends Thread{//发数据
    private Socket s=null;
    private QQClientFrame QQ;
    public TwoClientThread(Socket s,QQClientFrame QQ){
    this.s=s;
    this.QQ=QQ;

    }
    public void run(){
    try{
    String str=QQ.user+"  "+QQ.currentTime+" \n"+QQ.txtUserSend.getText()+" \n";
    QQ.output.println("Client:"+str);//向client发数据
    QQ.txtInfoShow.append(str);//显示数据
    QQ.txtUserSend.setText("");//清空
    }catch(Exception se){
    se.printStackTrace();
    }

    }

    }
    class ClientThread extends Thread{//接Server 数据
        private Socket s = null;
        private QQClientFrame QQ=null;
        public ClientThread(Socket s,QQClientFrame QQ){
            this.s = s;
            this.QQ=QQ;
        }
        public void run(){
        
            try {
             while(true){
             String str=QQ.input.readLine();
                 QQ.txtInfoShow.append(str+"\n");
             }
            
            
            } catch (Exception ioe) {
                ioe.printStackTrace();
            }    }}public class QQClientFrame extends JFrame{
        JPanel contentPane;
        JPanel jPanel1 = new JPanel();
        JScrollPane jScrollPane1 = new JScrollPane();
        JTextArea txtInfoShow = new JTextArea();
        JPanel jPanel2 = new JPanel();
        JButton bSend = new JButton();
        JButton bExit = new JButton();
        JScrollPane jScrollPane2 = new JScrollPane();
        JTextArea txtUserSend = new JTextArea();
        Socket sClient=null;
        JLabel ip = new JLabel();
        JTextField txtIP = new JTextField();
        JLabel port = new JLabel();
        JTextField txtPort = new JTextField();
        JButton bConnection = new JButton();
        String user=null;
        DataInputStream input=null;
        PrintStream output=null;
        String currentTime;
        public QQClientFrame() {
            try{
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                jbInit();
                this.setSize(500,500);
                this.setVisible(true);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        /**
         * Component initialization.
         *
         * @throws java.lang.Exception
         */
       private void jbInit() throws Exception {
            contentPane = (JPanel) getContentPane();
            contentPane.setLayout(null);
            setSize(new Dimension(513, 500));
            setTitle("[客 户 端]");
            jPanel1.setBorder(BorderFactory.createLineBorder(Color.black));
            jPanel1.setBounds(new Rectangle(5, 7, 348, 252));
            jPanel1.setLayout(null);
            jScrollPane1.setBounds(new Rectangle(4, 6, 336, 240));
            jPanel2.setBorder(BorderFactory.createLineBorder(Color.black));
            jPanel2.setBounds(new Rectangle(5, 265, 348, 119));
            jPanel2.setLayout(null);
            bSend.setBounds(new Rectangle(187, 393, 75, 29));
            bSend.setText("发送");
            bSend.addActionListener(new QQClientFrame_bSend_actionAdapter(this));
            bExit.setBounds(new Rectangle(280, 393, 75, 29));
            bExit.setText("关闭");
            bExit.addActionListener(new QQClientFrame_bExit_actionAdapter(this));
            jScrollPane2.setBounds(new Rectangle(3, 4, 340, 111));
            txtInfoShow.setEditable(false);
            ip.setText("服务器的 IP 地 址");
            ip.setBounds(new Rectangle(356, 9, 115, 28));
            txtIP.setBounds(new Rectangle(357, 40, 147, 26));
            port.setText("端 口");
            port.setBounds(new Rectangle(357, 74, 118, 24));
            txtPort.setBounds(new Rectangle(357, 100, 147, 26));
            bConnection.setBounds(new Rectangle(386, 166, 77, 33));
            bConnection.setText("连 接");
            bConnection.addActionListener(new
                                          QQClientFrame_bConnection_actionAdapter(this));
            contentPane.add(jPanel1);
            jPanel1.add(jScrollPane1);
            contentPane.add(jPanel2);
            jPanel2.add(jScrollPane2);
            jScrollPane2.getViewport().add(txtUserSend);
            contentPane.add(bExit);
            contentPane.add(bSend);
            contentPane.add(ip);
            contentPane.add(txtIP);
            contentPane.add(port);
            contentPane.add(txtPort);
            contentPane.add(bConnection);
            jScrollPane1.getViewport().add(txtInfoShow);
            txtUserSend.setText("aaaaa");
            txtIP.setText("127.0.0.1");
            txtPort.setText("888");
        }
        public void connection(){
         try{
         String ip=txtIP.getText();
                int port=Integer.parseInt(txtPort.getText());
                sClient=new Socket(ip,port);
                user=""+sClient.getInetAddress().getHostName();
                input=new DataInputStream(sClient.getInputStream());
                output=new PrintStream(sClient.getOutputStream());
                txtInfoShow.append(user+"连接成功\n");
                output.println(user+"连接成功\n");//可以接数据了..
                new ClientThread(sClient,this).start();
                
         }catch(Exception se){
         JOptionPane.showMessageDialog(null,"没有开服务器","系统提示",JOptionPane.ERROR_MESSAGE);
         se.printStackTrace();
         }
            
        }
        public static void main(String [] args){
         new QQClientFrame();
        }
     
        public void bSend_actionPerformed(ActionEvent e){
            String str = txtUserSend.getText();
            if (str.length() == 0) {
            JOptionPane.showMessageDialog(null,"请输入聊天信息","系统提示",JOptionPane.ERROR_MESSAGE);
            }else{
                Calendar time=Calendar.getInstance();
                time.get(Calendar.HOUR);
                String hour=""+time.get(Calendar.HOUR);
                String minute=""+time.get(Calendar.MINUTE);
                String second=""+time.get(Calendar.SECOND);
                if(hour.length()==1){
                    hour="0"+hour;
                }
                if(minute.length()==1){
                    minute="0"+minute;
                }
                if(second.length()==1){
                    second="0"+second;
                }
                currentTime=hour+":"+minute+":"+second;
                new TwoClientThread(sClient,this).start();
            }
        }
        public void bExit_actionPerformed(ActionEvent e) {
              this.dispose();
        }
        public void bConnection_actionPerformed(ActionEvent e) {
          if(txtIP.getText().length()!=0){
              if(txtPort.getText().length()!=0){
                  connection();
                  //txtInfoShow.append("连接成功...............\n\r");
              }else{
                 JOptionPane.showMessageDialog(null,"请输入端口号","系统提示",JOptionPane.ERROR_MESSAGE);
              }
          }else{
              JOptionPane.showMessageDialog(null,"请输入IP地址","系统提示",JOptionPane.ERROR_MESSAGE);
          }
        }
    }
    class QQClientFrame_bConnection_actionAdapter implements ActionListener {
        private QQClientFrame adaptee;
        QQClientFrame_bConnection_actionAdapter(QQClientFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bConnection_actionPerformed(e);
        }
    }
    class QQClientFrame_bExit_actionAdapter implements ActionListener {
        private QQClientFrame adaptee;
        QQClientFrame_bExit_actionAdapter(QQClientFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bExit_actionPerformed(e);
        }
    }
    class QQClientFrame_bSend_actionAdapter implements ActionListener {
        private QQClientFrame adaptee;
        QQClientFrame_bSend_actionAdapter(QQClientFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bSend_actionPerformed(e);
        }
    }
      

  2.   

    这个是serverclass TwoServerThread extends Thread{//发数据
    private Socket s;
    private QQServerFrame QQ;
    public TwoServerThread(Socket s,QQServerFrame QQ){
    this.s=s;
    this.QQ=QQ;
    }
    public void run(){
    try{
    String str=QQ.user+"  "+QQ.currentTime+"\n  "+QQ.txtUserSend.getText()+"\n";
    QQ.output.println("server:"+str);//向client发数据
    QQ.txtInfoShow.append(str);//显示数据
    QQ.txtUserSend.setText("");//清空
    }catch(Exception se){
    QQ.txtInfoShow.append("出错\n");
    se.printStackTrace();
    }
        } 
    }
    class oneServerThread extends Thread{//接数据
        private Socket s;
        private QQServerFrame QQ;
        public oneServerThread(Socket s,QQServerFrame QQ){
            this.s=s;
            this.QQ=QQ;
        }
        public void run(){
         try{
         while(true){
         String str=QQ.input.readLine();
             QQ.txtInfoShow.append("\n"+str);
         }
        
         }catch(Exception se){
         se.printStackTrace();
         }
     
        }  
        
    }
    public class QQServerFrame extends JFrame{
        JPanel contentPane;
        JPanel jPanel1 = new JPanel();
        JPanel jPanel2 = new JPanel();
        JScrollPane jScrollPane1 = new JScrollPane();
        JScrollPane jScrollPane2 = new JScrollPane();
        JTextArea txtInfoShow = new JTextArea();
        JTextArea txtUserSend = new JTextArea();
        JButton bSend = new JButton();
        JButton bExit = new JButton();
        private ServerSocket sSocket=null;
        private Socket sServer=null;
         String user="";
        JButton bStart = new JButton();
        JLabel jLabel1 = new JLabel();
        JTextField txtPort = new JTextField();
        String currentTime=null;
        DataInputStream input=null;
        PrintStream output=null;
        public QQServerFrame(){
            try {
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                jbInit();
                this.setSize(500,500);
                this.setVisible(true);
            }catch (Exception exception){
                exception.printStackTrace();
            }
        }
        public void connection(){//
            try{
                int port=Integer.parseInt(txtPort.getText().trim());
                sSocket=new ServerSocket(port);
                System.out.println("等待客户连接");
                txtInfoShow.append("等待客户连接\n");
                 sServer=sSocket.accept();
                    System.out.println("客户连接成功");
                     user=""+sServer.getInetAddress().getHostAddress();
                     txtInfoShow.append(user+"客户连接成功");
                      input=new DataInputStream(sServer.getInputStream());//输入流自动获的
                      output=new PrintStream(sServer.getOutputStream());//输出按发送获的
                      output.println("Server connection sucessful\n");//发到Client
                      new oneServerThread(sServer,this).start();
            }catch(Exception se){
             System.out.println("客户连接出错");
             txtInfoShow.append("客户连接出错\n");
                se.printStackTrace();
            }    }
        public static void main(String [] args){
         new QQServerFrame();
        }
        /**
         * Component initialization.
         *
         * @throws java.lang.Exception
         */
        private void jbInit() throws Exception {
            contentPane = (JPanel) getContentPane();
            contentPane.setLayout(null);
            setSize(new Dimension(477, 480));
            setTitle("[QQ 服 务 端]");
            jPanel1.setBorder(BorderFactory.createLineBorder(Color.black));
            jPanel1.setBounds(new Rectangle(3, 5, 368, 285));
            jPanel1.setLayout(null);
            jPanel2.setBorder(BorderFactory.createLineBorder(Color.black));
            jPanel2.setBounds(new Rectangle(3, 293, 367, 96));
            jPanel2.setLayout(null);
            jScrollPane1.setBounds(new Rectangle(2, 3, 361, 279));
            jScrollPane2.setBounds(new Rectangle(3, 3, 361, 88));
            bSend.setBounds(new Rectangle(222, 401, 85, 28));
            bSend.setText("发 送");
            bSend.addActionListener(new QQServerFrame_bSend_actionAdapter(this));
            bExit.setBounds(new Rectangle(380, 183, 90, 26));
            bExit.setText("退出");
            bExit.addActionListener(new QQServerFrame_bExit_actionAdapter(this));
            txtInfoShow.setEditable(false);
            bStart.setBounds(new Rectangle(372, 115, 98, 28));
            bStart.setText("开 启");
            bStart.addActionListener(new QQServerFrame_bStart_actionAdapter(this));
            jLabel1.setText("端 口 号");
            jLabel1.setBounds(new Rectangle(373, 6, 100, 23));
            txtPort.setBounds(new Rectangle(374, 30, 100, 23));
            txtPort.setText("888");
            txtPort.addKeyListener(new QQServerFrame_txtPort_keyAdapter(this));
            contentPane.add(jPanel1);
            jPanel1.add(jScrollPane1);
            jScrollPane1.getViewport().add(txtInfoShow);
            contentPane.add(jPanel2);
            contentPane.add(jLabel1);
            contentPane.add(txtPort);
            contentPane.add(bSend);
            contentPane.add(bExit);
            contentPane.add(bStart);
            jPanel2.add(jScrollPane2);
            jScrollPane2.getViewport().add(txtUserSend);
        }    public void bSend_actionPerformed(ActionEvent e) {
         String str=txtUserSend.getText().toString();
             Calendar time=Calendar.getInstance();
                time.get(Calendar.HOUR);
                String hour=""+time.get(Calendar.HOUR);
                String minute=""+time.get(Calendar.MINUTE);
                String second=""+time.get(Calendar.SECOND);
                if(hour.length()==1){
                    hour="0"+hour;
                }
                if(minute.length()==1){
                    minute="0"+minute;
                }
                if(second.length()==1){
                    second="0"+second;
                }
                currentTime=hour+":"+minute+":"+second;
                new TwoServerThread(sServer,this).start();
        }
        public void bExit_actionPerformed(ActionEvent e) {
            this.dispose();
        }    public void bStart_actionPerformed(ActionEvent e) {
         String port=txtPort.getText();
         if(port.length()==0){
         JOptionPane.showMessageDialog(null,"没有输入端口号","系统提示",JOptionPane.DEFAULT_OPTION);
        
         }else{
         txtInfoShow.append("Server start up..........\n");
             try{
                Thread.sleep(10);
               }catch(Exception se){
                se.printStackTrace();
              }
            connection();
          }
            
        }
        public void txtPort_keyTyped(KeyEvent e) {
            if (e.getKeyChar() > '9' || e.getKeyChar() < '0') {
                e.setKeyChar('\0');
                JOptionPane.showMessageDialog(null, "请输入数字哦!","系统提示",JOptionPane.ERROR_MESSAGE);
            }
        }
    class QQServerFrame_txtPort_keyAdapter extends KeyAdapter {
        private QQServerFrame adaptee;
        QQServerFrame_txtPort_keyAdapter(QQServerFrame adaptee) {
            this.adaptee = adaptee;
        }    public void keyTyped(KeyEvent e) {
            adaptee.txtPort_keyTyped(e);
        }
    }
    class QQServerFrame_bStart_actionAdapter implements ActionListener {
        private QQServerFrame adaptee;
        QQServerFrame_bStart_actionAdapter(QQServerFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bStart_actionPerformed(e);
        }
    }
    class QQServerFrame_bExit_actionAdapter implements ActionListener {
        private QQServerFrame adaptee;
        QQServerFrame_bExit_actionAdapter(QQServerFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bExit_actionPerformed(e);
        }
    }
    class QQServerFrame_bSend_actionAdapter implements ActionListener {
        private QQServerFrame adaptee;
        QQServerFrame_bSend_actionAdapter(QQServerFrame adaptee) {
            this.adaptee = adaptee;
        }    public void actionPerformed(ActionEvent e) {
            adaptee.bSend_actionPerformed(e);
        }
    }
    }
      

  3.   

    你的异常处理没处理好
    你的异常是直接抛给外部了,不受你控制
    你可以在你的net io的代码前后,加上try...catch代码块保护你的代码
    然后再将main函数右边的throws Exception删除另外,不要用太大帽子
    头多大就带多大的帽子
    针对你这里而言,IOException已经足够了
    尽量少用Exception,这会将RuntimeException也捕获,而实际上,这个无须程序捕获