• 计算机网络 编程 总结:


    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
  • 相关阅读:
    Java n个线程轮流打印数字的问题
    【我所认知的BIOS】—&gt; uEFI AHCI Driver(6) AtaAtapiPassThruSupported的局部变量们
    设备树学习之(二)点灯【转】
    设备树学习之(一)GPIO中断【转】
    S5PV210开发板 VGA测试【转】
    Linux VGA驱动移植实验【转】
    略过天涯 深入浅出VGA和DVI接口【转】
    基于FPGA的VGA可移植模块终极设计【转】
    字符串函数---strcmp()与strncmp()详解及实现【转】
    关于内存中栈和堆的区别(非数据结构中的堆和栈,区别)
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6640892.html
Copyright © 2020-2023  润新知