上后谈爱情

导航

 

1.如上图 在服务器与客户端进行通信的过程中 主要进行数据包的传递,

            1)对于客户端与客户端之间 应该是互不影响有独立管道,Java模拟过程中 使用多线程的方法对其进行处理,多个线程拥有各自的读写数据的功能

             2)对于服务器端 相当于中转站,对于来自于不同的客户端的消息请求 应该要分别进行处理,所以服务器端需要使用多线程方法(l来一个客户端就必须开启一个新的线程)同样共享 读写操作;2.


 

2. 编程理解:

       1) 客户端拥有各自的 send ,receive数据的功能,因此在编程中将 send 与 receive方法进行封装

      对于 send方法编程:

 1 package recover;
 2 
 3 import java.io.*;
 4 import java.net.Socket;
 5 
 6 import Cheat.CloseUtil;
 7 
 8 public class ClientSend implements Runnable{
 9   
10     /**DataInputStream : 从 控制台得到消息 
11      *  DataOutputStream: 将数据进行发送*/
12     private DataOutputStream dos;
13     private BufferedReader dis;
14     
15     private String name;
16     boolean isRunnable=true;
17     public ClientSend()
18     {
19         dis=new BufferedReader(new InputStreamReader(System.in));
20     }
21     // 从控制台得到消息
22      private String getMsgFromConsule() {
23         // TODO Auto-generated method stub
24         try {
25             return dis.readLine();
26         } catch (IOException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30         return null;
31     }
32     public ClientSend(Socket client,String name)
33     {
34         try {
35             // 从客户端进行输出
36             this.dos=new DataOutputStream(client.getOutputStream());
37             this.name=name;
38         } catch (IOException e) {
39             // TODO Auto-generated catch block
40             //e.printStackTrace();
41             isRunnable=true;
42             try {
43                 CloseUtil.closeAll(dos,dis);
44             } catch (IOException e1) {
45                 // TODO Auto-generated catch block
46                 e1.printStackTrace();
47             }
48         }
49         
50     }
51     
52     public void send(String msg)
53     {
54         if(null!=msg && !msg.equals(""))
55         {
56             try {
57                 dos.writeUTF(msg);
58                 dos.flush();
59             } catch (IOException e) {
60                 // TODO Auto-generated catch block
61                 e.printStackTrace();
62             }
63         }
64     }
65     @Override
66     public void run() {
67         // TODO Auto-generated method stub
68          while(isRunnable)
69              send( getMsgFromConsule());
70     }
71     
72     
73 }
View Code

   在client 中通过调用线程方式:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.net.Socket;
 5 import java.net.UnknownHostException;
 6 
 7 public class client2 {
 8 /**使用多线程概念
 9  * @throws IOException 
10  * @throws UnknownHostException */
11     public static void main(String[] args) throws UnknownHostException, IOException {
12         // TODO Auto-generated method stub
13         
14        // 建立私聊 必须从 控制台的得到pc 名称
15         System.out.println("进入到客户端");
16         
17         BufferedReader info=new BufferedReader(new InputStreamReader(System.in));
18         String name=null;
19         if((name=info.readLine())==null)
20             return;
21         
22     /************************使用多线程 --之上代码 输入名字理解**************************************/        
23         Socket client1=new Socket("localhost",9999);
24         
25         // 发送数据
26         new Thread(new Send(client1,name)).start();
27         new Thread(new Reader(client1)).start();
28     }
29 
30 }
View Code

 

   2). 同理对于服务器端 首先 对 读写操作 进行封装,主要是为了每一个 客户端预录 独立管道:

   注意:sendf方法 服务器将接收到的消息返回发送

            sendother:通过广播的方法将接受到消息发送其他人

 

 1 private class MyChanner implements Runnable{
 2           private DataInputStream dis;
 3           private DataOutputStream dos;
 4           private String name;
 5           boolean isRunnable=true;
 6           
 7           public MyChanner(Socket client) throws IOException
 8           {
 9               try {
10                 this.dis=new DataInputStream(client.getInputStream());
11                 
12                 this.dos=new DataOutputStream(client.getOutputStream());
13                 this.name=dis.readUTF();
14                 this.send("欢迎您"+"进入到聊天室");
15                 this.sendother(this.name+"进入聊天室");
16               } catch (IOException e) {
17                 // TODO Auto-generated catch block
18                 //e.printStackTrace();
19                 CloseUtil.closeAll(dis,dos);
20                 isRunnable=false;
21             }
22               
23           }
24           
25           private String receive() throws IOException
26           {
27               String msg="";
28              try {
29                 msg= dis.readUTF();
30             } catch (IOException e) {
31                 // TODO Auto-generated catch block
32                 //e.printStackTrace();
33                 CloseUtil.closeAll(dis);
34                 isRunnable=false;
35                 all.remove(this);
36             }
37             return msg;
38              
39           }
40           
41           private void send(String msg) throws IOException
42           {
43               if (msg==null || msg=="")
44                   return;
45               
46               try {
47                  dos.writeUTF(msg);
48                  dos.flush();
49             } catch (IOException e) {
50                 // TODO Auto-generated catch block
51                 //e.printStackTrace();
52                 CloseUtil.closeAll(dos);
53                 isRunnable=false;
54                 all.remove(this);
55             }
56              
57           }
58           private void sendother(String msg) throws IOException
59           {
60              // String msg=receive();
61               //遍历容器
62               for(MyChanner temp:all)
63               {
64                   if(temp==this)
65                       continue;
66                   //发送其他客户端
67                   temp.send(msg);
68               }
69           }
70           
71         @Override
72         public void run() {
73             // TODO Auto-generated method stub
74             while(isRunnable)
75             {
76                 try {
77                     sendother(receive());//明显自己发给自己
78                 } catch (IOException e) {
79                     // TODO Auto-generated catch block
80                     e.printStackTrace();
81                 }
82                 
83                 
84             }
85         }
86         
87     }
View Code

为了将  消息发送给其他客户端,使用 容器将所有的客户端都加入到容器中,通过关键字---客户主机之间映射,将消息发送给指定 客户端完成私聊的作用;

     2)通过 while循环 让服务器一直处在于不断地监听信息的状态,

 1 // 做成广播形式
 2     public void start() throws IOException
 3     {
 4         ServerSocket server=new ServerSocket(9999);
 5         
 6         while(true)
 7         {
 8             Socket socket=server.accept();
 9             
10             MyChanner channer1=new MyChanner(socket);
11             all.add(channer1);//加入容器中同一管理
12             new Thread(channer1).start();
13         }
14     }

整体程序:

  1 package Cheat;
  2 
  3 import java.io.DataInputStream;
  4 import java.io.DataOutputStream;
  5 import java.io.IOException;
  6 import java.net.ServerSocket;
  7 import java.net.Socket;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 
 11 /**1. 服务器保持独立,客户端进行服务器,每个客户端应该互不影响
 12  * 2. 对服务器进行多线程处理
 13  * 
 14  * 3. 将输入流与输出流进行封装*/
 15 public class Server1 {
 16 
 17     public static void main(String[] args) throws IOException {
 18         // TODO Auto-generated method stub
 19         new Server1().start();
 20         
 21     }
 22     // 做一个容器,将所有线程键入其中
 23     private List<MyChanner> all=new ArrayList<MyChanner>();    
 24     
 25     // 做成广播形式
 26     public void start() throws IOException
 27     {
 28         ServerSocket server=new ServerSocket(9999);
 29         
 30         while(true)
 31         {
 32             Socket socket=server.accept();
 33             
 34             MyChanner channer1=new MyChanner(socket);
 35             all.add(channer1);//加入容器中同一管理
 36             new Thread(channer1).start();
 37         }
 38     }
 39     
 40     private class MyChanner implements Runnable{
 41           private DataInputStream dis;
 42           private DataOutputStream dos;
 43           private String name;
 44           boolean isRunnable=true;
 45           
 46           public MyChanner(Socket client) throws IOException
 47           {
 48               try {
 49                 this.dis=new DataInputStream(client.getInputStream());
 50                 
 51                 this.dos=new DataOutputStream(client.getOutputStream());
 52                 this.name=dis.readUTF();
 53                 this.send("欢迎您"+"进入到聊天室");
 54                 this.sendother(this.name+"进入聊天室");
 55               } catch (IOException e) {
 56                 // TODO Auto-generated catch block
 57                 //e.printStackTrace();
 58                 CloseUtil.closeAll(dis,dos);
 59                 isRunnable=false;
 60             }
 61               
 62           }
 63           
 64           private String receive() throws IOException
 65           {
 66               String msg="";
 67              try {
 68                 msg= dis.readUTF();
 69             } catch (IOException e) {
 70                 // TODO Auto-generated catch block
 71                 //e.printStackTrace();
 72                 CloseUtil.closeAll(dis);
 73                 isRunnable=false;
 74                 all.remove(this);
 75             }
 76             return msg;
 77              
 78           }
 79           
 80           private void send(String msg) throws IOException
 81           {
 82               if (msg==null || msg=="")
 83                   return;
 84               
 85               try {
 86                  dos.writeUTF(msg);
 87                  dos.flush();
 88             } catch (IOException e) {
 89                 // TODO Auto-generated catch block
 90                 //e.printStackTrace();
 91                 CloseUtil.closeAll(dos);
 92                 isRunnable=false;
 93                 all.remove(this);
 94             }
 95              
 96           }
 97           private void sendother(String msg) throws IOException
 98           {
 99              // String msg=receive();
100               //遍历容器
101               for(MyChanner temp:all)
102               {
103                   if(temp==this)
104                       continue;
105                   //发送其他客户端
106                   temp.send(msg);
107               }
108           }
109           
110         @Override
111         public void run() {
112             // TODO Auto-generated method stub
113             while(isRunnable)
114             {
115                 try {
116                     sendother(receive());//明显自己发给自己
117                 } catch (IOException e) {
118                     // TODO Auto-generated catch block
119                     e.printStackTrace();
120                 }
121                 
122                 
123             }
124         }
125         
126     }
127 }
View Code

 

posted on 2017-03-29 17:40  上后谈爱情  阅读(206)  评论(0编辑  收藏  举报