zoukankan      html  css  js  c++  java
  • Java项目——聊天器

    准备工作:

    1.在服务端和客户端项目中都建立中间传递对象,implements序列化

     1 public class ContextDemo implements Serializable {
     2 
     3     // 0:上线 1:发送信息 2:下线 3:抖窗 4:发送文件
     4     private int type;
     5     private HashSet<String> clients;
     6     private String info;
     7     private String name;
     8     private String time;
     9     private String last;
    10     private ArrayList<Byte> list2;
    11 
    12     public String getLast() {
    13         return last;
    14     }
    15 
    16     public void setLast(String last) {
    17         this.last = last;
    18     }
    19     public ArrayList<Byte> getList2() {
    20         return list2;
    21     }
    22 
    23     public void setList2(ArrayList<Byte> list2) {
    24         this.list2 = list2;
    25     }
    26 
    27     public String getName() {
    28         return name;
    29     }
    30 
    31     public void setName(String name) {
    32         this.name = name;
    33     }
    34 
    35     public int getType() {
    36         return type;
    37     }
    38 
    39     public void setType(int type) {
    40         this.type = type;
    41     }
    42 
    43     public HashSet<String> getClients() {
    44         return clients;
    45     }
    46 
    47     public void setClients(HashSet<String> clients) {
    48         this.clients = clients;
    49     }
    50 
    51     public String getInfo() {
    52         return info;
    53     }
    54 
    55     public void setInfo(String info) {
    56         this.info = info;
    57     }
    58 
    59     public String getTime() {
    60         return time;
    61     }
    62 
    63     public void setTime(String time) {
    64         this.time = time;
    65     }
    66 
    67 }

    2.服务端实现监听

    服务端静态创建一个可以监听客户端连接的serversocket和可以存储在线用户名与socket的Hashmap,服务端开启监听,并在监听到任意客户端的连接时开启一个新的服务端监听线程(将该用户的socket通过构造函数传递给这个线程)

     1 public static ServerSocket ss;
     2     public static HashMap<String, Socket> online;
     3     public static Socket socket;
     4 
     5     static {
     6         try {
     7             ss = new ServerSocket(8080);
     8             System.out.println("服务器已开启");
     9             online = new HashMap<String, Socket>();
    10         } catch (IOException e) {
    11             e.printStackTrace();
    12         }
    13     }
    14 
    15     public void action() {
    16         try {
    17             while (true) {
    18                 Socket s = ss.accept();
    19                 System.out.println("服务器正在监听");
    20                 new Server_Thread(s).start();
    21             }
    22         } catch (IOException e) {
    23             // TODO Auto-generated catch block
    24             e.printStackTrace();
    25         }
    26     }
    27 
    28     public static void main(String[] args) {
    29 
    30         new Chat_Server().action();
    31 
    32     }

    线程中定义

    (1)发送给全部在线用户的方法,主要是通过创建Hashmap的iterator来实现遍历,获取到每一个在线用户的socket,并用这个用户的socket来建立outputstream进行消息的传递

     1 // 定义发送给全部用户的方法
     2         public void sendtoall(ContextDemo servercontext) {
     3             Collection<Socket> clients = online.values();
     4             Iterator<Socket> iterator = clients.iterator();
     5             ObjectOutputStream oo;
     6             while (iterator.hasNext()) {
     7 
     8                 Socket socket = iterator.next();
     9                 try {
    10                     oo = new ObjectOutputStream(socket.getOutputStream());
    11                     oo.writeObject(servercontext);
    12                     oo.flush();
    13                 } catch (IOException e) {
    14                     // TODO Auto-generated catch block
    15                     e.printStackTrace();
    16                 }
    17             }
    18         }

    (2)发送给指定用户的方法,方法实现与发送给全部用户的方法基本一致,只是需要进行判断,如果选中的用户中包含遍历出来的在线用户,再取socket进行发送

     1 // 定义发送给指定用户的方法
     2         public void sendtothis(ContextDemo servercontext) {
     3             HashSet<String> clients = clientcontext.getClients();
     4             Set<String> oo = online.keySet();
     5             Iterator<String> it = oo.iterator();
     6             //如果用的同一个输出流对象,可能会因前一个未写完而发生错误
     7             ObjectOutputStream ooo;
     8             while (it.hasNext()) {
     9                 String name = it.next();
    10                 if (clients.contains(name)) {
    11                     Socket s = online.get(name);
    12                     try {
    13                         ooo = new ObjectOutputStream(s.getOutputStream());
    14                         ooo.writeObject(servercontext);
    15                         ooo.flush();
    16                     } catch (IOException e) {
    17                         // TODO Auto-generated catch block
    18                         e.printStackTrace();
    19                     }
    20                 }
    21             }
    22         }

    注意:此时应该在其中单独定义一个objectoutputstream,因为写出的时候有时间差!!!此bug耗费10小时寻找!!!!(关掉一个客户端后,另外一个报IOexcption)

    线程开始不停地监听从客户端发过来的信息(中间传递对象),并判断type,通过switch语句执行不同的操作

    1 @Override
    2         public void run() {
    3             try {
    4                 while (true) {
    5                     in = new ObjectInputStream(socket.getInputStream());
    6                     clientcontext = (ContextDemo) in.readObject();
    7 
    8                     // 分析type的种类,来用以判断执行哪种操作
    9                     switch (clientcontext.getType()) {

    一、注册

    界面:

    获取到用户输入的用户名密码,进行一系列的判断,与配置文件中的数值进行比对,如果无误则保存当前用户输入的用户名、密码进配置文件,并成功登陆到聊天室界面(通过构造函数传递socket和username),否则则报错

     1 try {
     2             Properties userPro = new Properties();
     3             userPro.load(new FileInputStream("Users.properties"));
     4             
     5             String username = usertext.getText();
     6             String passwordFirst = new String(password1.getPassword());
     7             String passwordLast = new String(password2.getPassword());
     8             
     9             if (username.length() != 0) {
    10                 
    11                 if (userPro.containsKey(username)) {
    12                     JOptionPane.showMessageDialog(getContentPane(), "用户名已经存在!");
    13                 } else {
    14                     
    15                     if(passwordFirst.equals(passwordLast)){
    16                         if(passwordFirst.length()!=0){
    17                             userPro.setProperty(username, passwordFirst);
    18                             userPro.store(new FileOutputStream("Users.properties"), "用户名——密码");
    19                             
    20                             //进入聊天界面
    21                             Socket socket = new Socket("localhost", 8080);
    22                             ChatRoom chatRoom = new ChatRoom(username,socket);
    23                             chatRoom.setVisible(true);
    24                             setVisible(false);
    25                         }else {
    26                             JOptionPane.showMessageDialog(getContentPane(), "密码不能为空");
    27                         }
    28                     }else {
    29                         JOptionPane.showMessageDialog(getContentPane(), "两次输入密码不一致");
    30                     }
    31                 }
    32             } else {
    33                 JOptionPane.showMessageDialog(getContentPane(), "用户名不能为空");
    34             }
    35         }
    36         catch (FileNotFoundException e) {
    37             // TODO Auto-generated catch block
    38             e.printStackTrace();
    39         } catch (IOException e) {
    40             // TODO Auto-generated catch block
    41             e.printStackTrace();
    42         }

    二、登录

    界面:

    用户输入用户名和密码,此时通过与项目自带的properties配置文件中的内容进行比对,如果有记录,则可以进入到聊天室(通过设置了每个testfield和登录按钮的keypressed事件,可通过检测按下回车按钮进入),若没有,则要求进入注册界面。

    注意:如可以进入到聊天室界面,需要将此时新建的socket和用户名通过聊天室界面的构造函数传给聊天室。

     1 try {
     2             Properties properties = new Properties();
     3             properties.load(new FileInputStream("Users.properties"));
     4             
     5             String usernameString = textusername.getText();
     6             String pasString = new String(password1.getPassword());
     7             
     8             if(properties.containsKey(usernameString)){
     9                 if(properties.getProperty(usernameString).equals(pasString)){
    10                     Socket socket = new Socket("localhost", 8080);
    11                     ChatRoom chatRoom = new ChatRoom(usernameString,socket);
    12                     chatRoom.setVisible(true);
    13                     setVisible(false);
    14                 }else {
    15                     JOptionPane.showMessageDialog(getContentPane(), "密码输入错误");
    16                 }
    17             }else {
    18                 JOptionPane.showMessageDialog(getContentPane(), "该用户名不存在");
    19             }

    三、聊天室主界面

    界面:

    1.本用户上线报告服务器+服务器将该用户上线信息发送给全部用户

    (1)客户端的构造函数中,将本用户的socket,用户名,当前系统时间,中间传递对象的类型(上线类型为0),封装进中间传递对象并通过socket的outputstream发送给服务端,并开启客户端线程进行监控服务端传过来的信息

     1 // 上线则汇报给服务器
     2         try {
     3             
     4             out = new ObjectOutputStream(socket.getOutputStream());
     5             // 创建传输对象
     6             ContextDemo clientcontext = new ContextDemo();
     7             clientcontext.setType(0);
     8             clientcontext.setName(username);
     9             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    10             clientcontext.setTime(sdf.format(new Date()));
    11             // 发送给服务端
    12             out.writeObject(clientcontext);
    13             out.flush();
    14             // 开启客户端线程
    15             new Client_Thread().start();
    16 
    17         } catch (IOException e) {
    18             // TODO Auto-generated catch block
    19             e.printStackTrace();
    20         }

    客户端线程开始监听

    1 @Override
    2         public void run() {
    3 
    4             try {
    5                 while (true) {
    6                     System.out.println("客户端线程启动");
    7                     in = new ObjectInputStream(socket.getInputStream());
    8                     final ContextDemo servercontext = (ContextDemo) in.readObject();
    9                     switch (servercontext.getType()) {

    (2)服务端得到该用户的中间传递对象,判断出执行上线操作,执行相应的switch语句,将用户名与socket存入hashmap,并创建当前用户的上线信息,对象类型type,以及在线用户名的集合封装进对象发送给所有的在线用户

     1 // 上线
     2                     case 0:
     3                     // 添加在线用户进online
     4                     {
     5 
     6                         online.put(clientcontext.getName(), socket);
     7 
     8                         ContextDemo serverContext = new ContextDemo();
     9                         // 将用户上线信息发送给各客户端
    10                         serverContext.setType(0);
    11                         serverContext.setInfo(clientcontext.getTime() + " " + clientcontext.getName() + " 上线啦!");
    12                         // 将在线用户用户名全部发给客户端
    13                         HashSet<String> set = new HashSet<String>();
    14                         set.addAll(online.keySet());
    15                         serverContext.setClients(set);
    16                         sendtoall(serverContext);
    17                         break;
    18                     }

    (3)客户端监听到信息,判断出为上下线更新操作,先清空在线列表集合,在将所要取得的各种信息从对象中取得,并获取到在线人数集合中数目以实现在线人数显示,并将上线消息显示在testArea中

     1 case 0:
     2                     // 重新装填容器
     3                     {
     4                         // 清空容器
     5                         online.clear();
     6                         HashSet<String> set = servercontext.getClients();
     7                         Iterator<String> iterator = set.iterator();
     8                         while (iterator.hasNext()) {
     9                             String name = iterator.next();
    10                             if (username.equals(name)) {
    11                                 online.add(name + "(本机)");
    12 
    13                             } else {
    14                                 online.add(name);
    15                             }
    16                         }
    17 
    18                         // 显示在list中
    19                         listmodel = new UUListModel(online);
    20                         count = listmodel.getSize();
    21                         list.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "在线用户:"+count+"人",
    22                                 TitledBorder.LEADING, TitledBorder.TOP, null, new Color(255, 0, 0)));
    23                         list.setModel(listmodel);
    24                         docs.insertString(docs.getLength(), servercontext.getInfo() + "
    ", attrset);
    25                         break;
    26                     }

    2.发送消息

    (1)客户端获取到list中选中的用户(若不选则为群发),将该选中用户、自己的用户名、时间、要发送的信息等内容封装进对象,设置type为1(发送信息识别码),将对象传递给服务器,在自己的聊天界面添加聊天的内容,随后清空list表的选中状态以及发送框的内容(发送按钮与回车键均可发送消息)

     1 // 发送按钮
     2         JButton btnNewButton = new JButton("u53D1u9001");
     3         btnNewButton.addActionListener(new ActionListener() {
     4             public void actionPerformed(ActionEvent arg0) {
     5 
     6                 List selected = list.getSelectedValuesList();
     7                 String info = textArea_1.getText();
     8 
     9                 if (selected.size() < 1) {
    10                     // 在客户端中,容器online中本机的名字后面多加了字符,所以在客户端不能与hashmap中的key匹配,所以本机收不到本机传来的信息
    11                     selected = online;
    12                 }
    13 
    14                 if (info.equals("")) {
    15                     JOptionPane.showMessageDialog(getContentPane(), "不能发送空信息");
    16                     return;
    17                 }
    18 
    19                 ContextDemo clientcontext = new ContextDemo();
    20                 clientcontext.setInfo(info);
    21                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    22                 String time = sdf.format(new Date());
    23                 clientcontext.setTime(time);
    24                 clientcontext.setType(1);// 发信息
    25                 clientcontext.setName(username);
    26                 HashSet<String> people = new HashSet<String>();
    27                 people.addAll(selected);
    28                 
    29                 clientcontext.setClients(people);
    30 
    31                 // 清空发送页面
    32                 textArea_1.setText("");
    33                 // 发送界面获得焦点
    34                 textArea_1.requestFocus();
    35                 // 列表消除选中状态
    36                 list.clearSelection();
    37 
    38                 try {
    39                     out = new ObjectOutputStream(ChatRoom.socket.getOutputStream());
    40                     out.writeObject(clientcontext);
    41                     out.flush();
    42                 } catch (IOException e) {
    43                     // TODO Auto-generated catch block
    44                     e.printStackTrace();
    45                 }
    46 
    47                 try {
    48                     docs.insertString(docs.getLength(), time + " " + "我对"+selected+"说:
    " + info + "
    ", attrset);
    49                 } catch (BadLocationException e) {
    50                     // TODO Auto-generated catch block
    51                     e.printStackTrace();
    52                 }
    53             }
    54         });

    (2)服务器判断出为发送消息后,将得到的信息、时间等消息进行封装,再通过发送给指定用户的方法将封装好的对象传递给指定的用户

     1 // 发信息
     2                     case 1: {
     3                         ContextDemo servercontext = new ContextDemo();
     4                         servercontext.setType(1);
     5                         servercontext.setName(clientcontext.getName());
     6                         servercontext.setInfo(clientcontext.getInfo());
     7                         servercontext.setTime(clientcontext.getTime());
     8 
     9                         sendtothis(servercontext);
    10                         break;
    11                     }

    (3)指定的客户端收到对象后判断出了是要进行发送消息的操作,解封对象,取得消息等信息,在消息窗口显示

    1 // 发信息
    2                     case 1: {
    3                         String info = servercontext.getInfo();
    4                         String time = servercontext.getTime();
    5                         docs.insertString(docs.getLength(),
    6                                 time + " " + servercontext.getName() + "对我说:
    " + info + "
    ", attrset);
    7                         break;
    8                     }

    3.下线

    (1)聊天室页面添加窗口关闭的监听事件,在其后弹出对话框确定是否退出,若退出则设置type为2(下线识别码)、时间等信息封装进对象发送给服务器

     1 // 下线操作
     2                 this.addWindowListener(new WindowAdapter() {
     3                     @Override
     4                     public void windowClosing(WindowEvent e) {
     5                         
     6                         int result = JOptionPane.showConfirmDialog(getContentPane(),"您确定要离开聊天室");
     7                         if (result == 0) {
     8                             ContextDemo clientcontext = new ContextDemo();
     9                             clientcontext.setType(2);
    10                             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    11                             clientcontext.setTime(sdf.format(new Date()));
    12                             clientcontext.setName(username);
    13 
    14                             try {
    15                                 out = new ObjectOutputStream(socket.getOutputStream());
    16                                 out.writeObject(clientcontext);
    17                                 out.flush();
    18                             } catch (IOException e1) {
    19                                 // TODO Auto-generated catch block
    20                                 e1.printStackTrace();
    21                             }
    22                         }
    23                         }
    24                 });

    (2)服务器判断为是下线操作后,首先建立服务端对象,设置type为2,用当前用户传递过来的socket传递此对象给即将下线的客户端批准其下线,随后用下线用户的用户名在Hashmap中删除此用户,随后新建另一服务端对象,封装下线的信息、时间、当前在线用户名等内容发送给其余所有在线的客户端,让他们执行上下线更新操作,并在case的最后用return退出whlie(true)循环,在finally中关闭掉输入输出流对象与socket对象,意在此客户端与服务端的线程关闭

     1 // 下线
     2                     case 2: {
     3                         // 通知请求下线客户端,批准下线
     4                         ContextDemo servercontext1 = new ContextDemo();
     5                         servercontext1.setType(2);
     6                         out = new ObjectOutputStream(socket.getOutputStream());
     7                         out.writeObject(servercontext1);
     8                         out.flush();//需要时间
     9 
    10                         // 刷新在线hashmap
    11                         online.remove(clientcontext.getName());
    12 
    13                         // 通知其他在线用户,该用户已下线
    14                         ContextDemo servercontext2 = new ContextDemo();
    15                         servercontext2.setType(0);
    16                         servercontext2.setInfo(clientcontext.getTime() + " " + clientcontext.getName() + "用户已下线 ");
    17                         HashSet<String> set = new HashSet<String>();
    18                         set.addAll(online.keySet());
    19                         servercontext2.setClients(set);
    20                         sendtoall(servercontext2);
    21                         // 退出当前循环,不再监听该客户端传来的信息
    22                         return;
    23                     }

    (3)

    1)即将下线的客户端接收到对象后,判断出是执行下线操作,用return退出while(true),并在finally中关闭掉socket与输入输出流对象,并用System.exit(0)退出虚拟机断线

    1 // 下线
    2                     case 2:{
    3                         return;
    4                     }

    2)其余在线客户端接收到对象,判断是要进行上下线操作,所以执行与上线更新时一样的操作

     1 // 上下线刷新操作
     2                     case 0:
     3                     // 重新装填容器
     4                     {
     5                         // 清空容器
     6                         online.clear();
     7                         HashSet<String> set = servercontext.getClients();
     8                         Iterator<String> iterator = set.iterator();
     9                         while (iterator.hasNext()) {
    10                             String name = iterator.next();
    11                             if (username.equals(name)) {
    12                                 online.add(name + "(本机)");
    13 
    14                             } else {
    15                                 online.add(name);
    16                             }
    17                         }
    18 
    19                         // 显示在list中
    20                         listmodel = new UUListModel(online);
    21                         count = listmodel.getSize();
    22                         list.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "在线用户:"+count+"人",
    23                                 TitledBorder.LEADING, TitledBorder.TOP, null, new Color(255, 0, 0)));
    24                         list.setModel(listmodel);
    25                         docs.insertString(docs.getLength(), servercontext.getInfo() + "
    ", attrset);
    26                         break;
    27                     }

    4.抖窗

    (1)客户端将列表中得到的用户名封装进对象,设置type为3,再将时间等信息封装进对象,将对象发送给服务端

     1 btnShakeFrame.addActionListener(new ActionListener() {
     2             public void actionPerformed(ActionEvent e) {
     3 
     4                 List selected = list.getSelectedValuesList();
     5 
     6                 if (selected.size() < 1) {
     7                     // 在客户端中,容器online中本机的名字后面多加了字符,所以在客户端不能与hashmap中的key匹配,所以本机收不到本机传来的信息
     8                     selected = online;
     9                 }
    10 
    11                 ContextDemo clientcontext = new ContextDemo();
    12                 clientcontext.setType(3);
    13                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    14                 String time = sdf.format(new Date());
    15                 clientcontext.setTime(time);
    16                 clientcontext.setName(username);
    17                 HashSet<String> set = new HashSet<String>();
    18                 set.addAll(selected);
    19                 clientcontext.setClients(set);
    20 
    21                 // 列表消除选中状态
    22                 list.clearSelection();
    23 
    24                 try {
    25                     out = new ObjectOutputStream(socket.getOutputStream());
    26                     out.writeObject(clientcontext);
    27                     out.flush();
    28                 } catch (IOException e1) {
    29                     // TODO Auto-generated catch block
    30                     e1.printStackTrace();
    31                 }
    32 
    33                 try {
    34                     docs.insertString(docs.getLength(), time + "您发送了一个屏幕抖动
    ", attrset);
    35                 } catch (BadLocationException e1) {
    36                     // TODO Auto-generated catch block
    37                     e1.printStackTrace();
    38                 }
    39             }
    40         });

    (2)服务端判断出是要进行抖窗操作后,封装有用的信息进对象,并通过发送给指定用户方法进行发送

    1 // 抖窗
    2                     case 3: {
    3                         ContextDemo servercontext = new ContextDemo();
    4                         servercontext.setType(3);
    5                         servercontext.setInfo(clientcontext.getTime() + " " + clientcontext.getName() + "对你抖了一下屏 
    ");
    6 
    7                         sendtothis(servercontext);
    8                         break;
    9                     }

    (3)指定的客户端判断要进行抖屏,先解封有用的信息进消息显示窗口,然后再调用封装好的抖屏方法进行抖屏操作

    1 // 抖窗
    2                     case 3: {
    3                         String info = servercontext.getInfo();
    4                         docs.insertString(docs.getLength(), info, attrset);
    5                         shakeFrame();
    6                         break;
    7                     }
     1 public void shakeFrame() {
     2         int x = ChatRoom.this.getX();
     3         int y = ChatRoom.this.getY();
     4         for (int i = 0; i < 20; i++) {
     5             if ((i & 1) == 0) {
     6                 x += 8;
     7                 y += 8;
     8             } else {
     9                 x -= 8;
    10                 y -= 8;
    11             }
    12             ChatRoom.this.setLocation(x, y);
    13             try {
    14                 Thread.sleep(50);
    15             } catch (InterruptedException e1) {
    16                 e1.printStackTrace();
    17             }
    18         }
    19     }

    5.发送文件

    (1)客户端先获取到想要发送文件给哪个用户的用户名,随后弹出文件选择框,构建文件的抽象路径,并得到后缀名,其后通过文件的输入流将所得到的文件一个字节一个字节的读入到Arraylist<byte>集合中,将后缀名保存到一个字符串中,将这些与其他有用的信息一起封装进对象,将对象发送给服务器

      1 btnSendFile.addActionListener(new ActionListener() {
      2             public void actionPerformed(ActionEvent e) {
      3                 
      4                 List selected = list.getSelectedValuesList();
      5                 if (selected.size() < 1) {
      6                     JOptionPane.showMessageDialog(getContentPane(), "必须选择一名用户");
      7                     return;
      8                 }
      9                 if (selected.toString().contains(username+"(本机)")) {
     10                     JOptionPane.showMessageDialog(getContentPane(), "不能向自己发送文件");
     11                     return;
     12                 }
     13                 
     14                 JFileChooser chooser = new JFileChooser();
     15                 chooser.setDialogTitle("选择文件框"); 
     16                 chooser.showDialog(getContentPane(), "选择");
     17                 
     18                 //判断是否拿到文件
     19                 if(chooser.getSelectedFile()!=null){
     20                     path = chooser.getSelectedFile().getPath();
     21                     file = new File(path);
     22                     //获取文件的后缀名
     23                     int i =file.getName().indexOf(".");
     24                     last = file.getName().substring(i);
     25                 
     26                     //判断文件是否为空
     27                     if(file.length()==0){
     28                         JOptionPane.showMessageDialog(getContentPane(), "文件为空,不能传送");
     29                         return;
     30                     }
     31                 }
     32                 
     33                 ContextDemo clientcontext = new ContextDemo();
     34                 //发送文件(基础工作)
     35                 clientcontext.setType(4);
     36                 //保存后缀名
     37                 clientcontext.setLast(last);
     38                 clientcontext.setName(username);
     39                 HashSet<String> set = new HashSet<String>();
     40                 set.addAll(selected);
     41                 clientcontext.setClients(set);
     42                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     43                 String time = sdf.format(new Date());
     44                 clientcontext.setTime(time);
     45                 
     46                 //发送文件(文件部分操作)
     47                 list2 = new ArrayList<Byte>();
     48                 try {
     49                     input = new FileInputStream(file);
     50                     
     51                     int result = -1;
     52                     
     53                     while((result = input.read()) != -1)
     54                     {
     55                         list2.add((byte)result);
     56                     }
     57                     
     58                     
     59                     
     60                 } catch (FileNotFoundException e2) {
     61                     // TODO Auto-generated catch block
     62                     e2.printStackTrace();
     63                 } catch (IOException e1) {
     64                     // TODO Auto-generated catch block
     65                     e1.printStackTrace();
     66                 }finally {
     67                     
     68                     try {
     69                         if(input != null)
     70                         {
     71                             input.close();
     72                         }
     73                     } catch (IOException e1) {
     74                         e1.printStackTrace();
     75                     }
     76                 }
     77                 
     78                 clientcontext.setList2(list2);
     79                 
     80                 
     81                 // 列表消除选中状态
     82                 list.clearSelection();
     83                 
     84                 //发送给服务端
     85                 try {
     86                     out = new ObjectOutputStream(socket.getOutputStream());
     87                     out.writeObject(clientcontext);
     88                     out.flush();
     89                 } catch (IOException e1) {
     90                     // TODO Auto-generated catch block
     91                     e1.printStackTrace();
     92                 }
     93 
     94                 try {
     95                     docs.insertString(docs.getLength(), time + "您发送了一个文件
    ", attrset);
     96                 } catch (BadLocationException e1) {
     97                     // TODO Auto-generated catch block
     98                     e1.printStackTrace();
     99                 }
    100             }
    101         });
    102         

    (2)服务端判断出是要进行文件的发送操作,将所有有用的信息封装进对象发送给指定的用户

     1 // 发送文件
     2                     case 4: {
     3                         ContextDemo servercontext = new ContextDemo();
     4                         servercontext.setList2(clientcontext.getList2());
     5                         servercontext.setLast(clientcontext.getLast());
     6                         servercontext.setInfo(clientcontext.getTime() + " " + clientcontext.getName() + "对你发送了一个文件
    ");
     7                         servercontext.setType(4);
     8 
     9                         sendtothis(servercontext);
    10 
    11                         break;
    12                     }

    (3)指定客户端收到对象后,先将字节集合解封出来,用iterator将字节写入一个字节数组,再通过缓冲字节流读入字节,通过解封出来的后缀名构造好新的文件后,通过缓冲字节流写入文件,并接收到需要的信息显示在消息窗口中

     1 //接收到文件
     2                     case 4:
     3                     {
     4                         ArrayList<Byte> list3 = new ArrayList<Byte>();
     5                         list3 = servercontext.getList2();
     6                         Iterator<Byte> it = list3.iterator();
     7                         byte[] dedao = new byte[10000000];
     8                         int i = 0;
     9                         while(it.hasNext()){
    10                             dedao[i] = it.next();
    11                             i++;
    12                         }
    13                         
    14                         
    15                         ii = new ByteArrayInputStream(dedao);
    16                         inputStream = new BufferedInputStream(ii,10000);
    17                         //获取后缀名
    18                         String thLast = servercontext.getLast();
    19                         output = new FileOutputStream("sourse/dedao"+thLast);
    20                         outputStream = new BufferedOutputStream(output,10000);
    21                         
    22                         byte[] b = new byte[10000];//暂存读取的字节内容
    23                         int result = -1;
    24                         while((result = inputStream.read(b)) != -1)
    25                         {
    26                             outputStream.write(b, 0, result);
    27                         }
    28                         output.flush();
    29                         
    30                         
    31                         
    32                         String info = servercontext.getInfo();
    33                         docs.insertString(docs.getLength(), info, attrset);
    34                         break;
    35                     }
  • 相关阅读:
    suse12安装详解
    Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
    菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]
    openstack中dashboard页面RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
    Multiple network matches found for name 'selfservice', use an ID to be more specific.报错
    查看 SELinux状态及关闭SELinux
    SELinux深入理解
    IP地址、子网掩码、网络号、主机号、网络地址、主机地址
    Oracle job procedure 存储过程定时任务
    POI文件导出至EXCEL,并弹出下载框
  • 原文地址:https://www.cnblogs.com/ccw95/p/5969469.html
Copyright © 2011-2022 走看看