A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 刘学明    于 2013-4-21 00:19 编辑

一个客户端程序  一个服务端程序  
基本功能实现了 当开启多个客户端窗口进行聊天   先关闭其中的一个客户端  用其他客户端进行发送消息时
会报出  Socket close 的错误 请问如何完善程序才可以
服务端程序代码:

  1. import java.io.*;
  2. import java.net.*;
  3. import java.util.*;

  4. public class ChatServer {
  5.         boolean started = false;
  6.         ServerSocket ss = null;
  7.         
  8.         List<Client> clients = new ArrayList<Client>();
  9.         
  10.         public static void main(String[] args) {
  11.                 new ChatServer().start();
  12.         }
  13.         
  14.         public void start() {
  15.                 try {
  16.                         ss = new ServerSocket(8888);
  17.                         started = true;
  18.                 } catch (BindException e) {
  19.                         System.out.println("端口使用中....");
  20.                         System.out.println("请关掉相关程序并重新运行服务器!");
  21.                         System.exit(0);
  22.                 } catch (IOException e) {
  23.                         e.printStackTrace();
  24.                 }
  25.                
  26.                 try {
  27.                         
  28.                         while(started) {
  29.                                 Socket s = ss.accept();
  30.                                 Client c = new Client(s);
  31.                                 System.out.println("a client connected!");
  32.                                 new Thread(c).start();
  33.                                 clients.add(c);
  34.                         }
  35.                 } catch (IOException e) {
  36.                         e.printStackTrace();
  37.                 } finally {
  38.                         try {
  39.                                 ss.close();
  40.                         } catch (IOException e) {
  41.                                 e.printStackTrace();
  42.                         }
  43.                 }
  44.         }
  45.         
  46.         class Client implements Runnable {
  47.                 private Socket s;
  48.                 private DataInputStream dis = null;
  49.                 private DataOutputStream dos = null;
  50.                 private boolean bConnected = false;
  51.                
  52.                 public Client(Socket s) {
  53.                         this.s = s;
  54.                         try {
  55.                                 dis = new DataInputStream(s.getInputStream());
  56.                                 dos = new DataOutputStream(s.getOutputStream());
  57.                                 bConnected = true;
  58.                         } catch (IOException e) {
  59.                                 e.printStackTrace();
  60.                         }
  61.                 }
  62.                
  63.                 public void send(String str) {
  64.                         try {
  65.                                 dos.writeUTF(str);
  66.                         } catch (IOException e) {
  67.                                 e.printStackTrace();
  68.                         }
  69.                 }
  70.                
  71.                 public void run() {
  72.                         try {
  73.                                 while(bConnected) {
  74.                                         String str = dis.readUTF();
  75.                                         System.out.println(str);
  76.                                         for(int i=0; i<clients.size(); i++) {
  77.                                                 Client c = clients.get(i);
  78.                                                 c.send(str);
  79.                                         }
  80.                                 }
  81.                         } catch (EOFException e) {
  82.                                 System.out.println("Client closed!");
  83.                         } catch (IOException e) {
  84.                                 e.printStackTrace();
  85.                         } finally {
  86.                                 try {
  87.                                         if(dis != null) dis.close();
  88.                                         if(dos != null) dos.close();
  89.                                         if(s != null)  {
  90.                                                 s.close();
  91.                                         }
  92.                                 } catch (IOException e1) {
  93.                                         e1.printStackTrace();
  94.                                 }
  95.                         }
  96.                 }
  97.         }
  98. }

复制代码
客户端程序代码:
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import java.io.*;
  4. import java.net.*;

  5. public class ChatClient extends Frame {
  6.         Socket s = null;
  7.         DataOutputStream dos = null;
  8.         DataInputStream dis = null;
  9.         private boolean bConnected = false;

  10.         TextField tfTxt = new TextField();

  11.         TextArea taContent = new TextArea();
  12.         
  13.         Thread tRecv = new Thread(new RecvThread());

  14.         public static void main(String[] args) {
  15.                 new ChatClient().launchFrame();
  16.         }

  17.         public void launchFrame() {
  18.                 setLocation(400, 300);
  19.                 this.setSize(300, 300);
  20.                 add(tfTxt, BorderLayout.SOUTH);
  21.                 add(taContent, BorderLayout.NORTH);
  22.                 pack();
  23.                 this.addWindowListener(new WindowAdapter() {

  24.                         @Override
  25.                         public void windowClosing(WindowEvent arg0) {
  26.                                 disconnect();
  27.                                 System.exit(0);
  28.                         }
  29.                         
  30.                 });
  31.                 tfTxt.addActionListener(new TFListener());
  32.                 setVisible(true);
  33.                 connect();
  34.                
  35.                 tRecv.start();
  36.         }
  37.         
  38.         public void connect() {
  39.                 try {
  40.                         s = new Socket("127.0.0.1", 8888);
  41.                         dos = new DataOutputStream(s.getOutputStream());
  42.                         dis = new DataInputStream(s.getInputStream());
  43.                         System.out.println("connected!");
  44.                         bConnected = true;
  45.                 } catch (UnknownHostException e) {
  46.                         e.printStackTrace();
  47.                 } catch (IOException e) {
  48.                         e.printStackTrace();
  49.                 }
  50.                
  51.         }
  52.         
  53.         public void disconnect() {
  54.                 try {
  55.                         dos.close();
  56.                         dis.close();
  57.                         s.close();
  58.                 } catch (IOException e) {
  59.                         e.printStackTrace();
  60.                 }
  61.         }
  62.         
  63.         private class TFListener implements ActionListener {

  64.                 public void actionPerformed(ActionEvent e) {
  65.                         String str = tfTxt.getText().trim();
  66.                         tfTxt.setText("");
  67.                         
  68.                         try {
  69.                                 dos.writeUTF(str);
  70.                                 dos.flush();
  71.                         } catch (IOException e1) {
  72.                                 e1.printStackTrace();
  73.                         }
  74.                         
  75.                 }
  76.                
  77.         }
  78.         
  79.         private class RecvThread implements Runnable {

  80.                 public void run() {
  81.                         try {
  82.                                 while(bConnected) {
  83.                                         String str = dis.readUTF();
  84.                                         taContent.setText(taContent.getText() + str + '\n');
  85.                                 }
  86.                         } catch (SocketException e) {
  87.                                 System.out.println("退出了,bye!");
  88.                         } catch (IOException e) {
  89.                                 e.printStackTrace();
  90.                         }
  91.                 }
  92.         }
  93. }


复制代码
一个客户端 一个服务端  开启多个客户端进行聊天  关闭了其中一个客户端  其它的没关闭的客户端只要一发送消息    就会报出Socket Close的异常错误    是阻塞式方法WriteUTF()和ReadUTF()的原因吗   怎么修改程序

1.jpg (50.74 KB, 下载次数: 13)

1.jpg

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

3 个回复

倒序浏览
好长啊  如果说这段代码肯定是  网络流已经关闭了,好好跟老毕的视频对照一下看看哪里出问题了。
回复 使用道具 举报
本帖最后由 孙胜 于 2013-4-27 23:05 编辑

你的问题在于关闭客户端是,并没有把这个客户端从集合中删除,这样就造成了向一个不存在的客户端发送消息,所以会报异常
我把你的代码修改了下,运行结果就没问题了

  1. import java.io.*;
  2. import java.net.*;
  3. import java.util.*;

  4. public class ChatServer {
  5.         boolean started = false;
  6.         ServerSocket ss = null;
  7.         
  8.         
  9.         Client client;<font color="#ff0000" size="5">//这里增加一个变量声明,run方法关闭资源前把客户端从集合中删除</font>
  10.         List<Client> clients = new ArrayList<Client>();
  11.         
  12.         public static void main(String[] args) {
  13.                 new ChatServer().start();
  14.         }
  15.         
  16.         public void start() {
  17.                 try {
  18.                         ss = new ServerSocket(8888);
  19.                         started = true;
  20.                 } catch (BindException e) {
  21.                         System.out.println("端口使用中....");
  22.                         System.out.println("请关掉相关程序并重新运行服务器!");
  23.                         System.exit(0);
  24.                 } catch (IOException e) {
  25.                         e.printStackTrace();
  26.                 }
  27.                
  28.                 try {
  29.                         
  30.                         while(started) {<font size="5" color="#ff0000">//把你原来的c换成client</font>
  31.                                 Socket s = ss.accept();
  32.                                 client = new Client(s);
  33.                                 System.out.println("a client connected!");
  34.                                 new Thread(client).start();
  35.                                 clients.add(client);
  36.                         }
  37.                 } catch (IOException e) {
  38.                         e.printStackTrace();
  39.                 } finally {
  40.                         try {
  41.                                 ss.close();
  42.                         } catch (IOException e) {
  43.                                 e.printStackTrace();
  44.                         }
  45.                 }
  46.         }
  47.         
  48.         class Client implements Runnable {
  49.                 private Socket s;
  50.                 private DataInputStream dis = null;
  51.                 private DataOutputStream dos = null;
  52.                 private boolean bConnected = false;
  53.                
  54.                 public Client(Socket s) {
  55.                         this.s = s;
  56.                         try {
  57.                                 dis = new DataInputStream(s.getInputStream());
  58.                                 dos = new DataOutputStream(s.getOutputStream());
  59.                                 bConnected = true;
  60.                         } catch (IOException e) {
  61.                                 e.printStackTrace();
  62.                         }
  63.                 }
  64.                
  65.                 public void send(String str) {
  66.                         try {
  67.                                 dos.writeUTF(str);
  68.                         } catch (IOException e) {
  69.                                 e.printStackTrace();
  70.                         }
  71.                 }
  72.                
  73.                 public void run() {
  74.                         try {
  75.                                 while(bConnected) {
  76.                                         String str = dis.readUTF();
  77.                                         System.out.println(str);
  78.                                         for(int i=0; i<clients.size(); i++) {
  79.                                                 Client c = clients.get(i);
  80.                                                 c.send(str);
  81.                                         }
  82.                                        
  83.                                 }
  84.                         } catch (EOFException e) {
  85.                                 System.out.println("Client closed!");
  86.                         } catch (IOException e) {
  87.                                 e.printStackTrace();
  88.                         } finally {
  89.                                 
  90.                                 clients.remove(client);<font color="#ff0000" size="5">//这里增加一行</font>
  91.                                 try {
  92.                                         if(dis != null) dis.close();
  93.                                         if(dos != null) dos.close();
  94.                                         if(s != null)  {
  95.                                                 s.close();
  96.                                         }
  97.                                 } catch (IOException e1) {
  98.                                         e1.printStackTrace();
  99.                                 }
  100.                         }
  101.                 }
  102.         }
  103. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报

如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马