(十四)Core Java 网络编程(网络模型详解,UDP聊天,TCP数据传输)-01 (110)

目录 :          
1 ) . 网络编程(概述)


2 ) .  网络编程(网络模型)


3 ) .   网络编程(IP地址)


4 ) .  网络编程(TCP和UDP)


5 ) .  网络编程(Socket)


6 ) .  网络编程(Udp-发送端)


7 ) .   网络编程(Udp-接收端)


8 ) .  网络编程(Udp-键盘录入方式数据)


9 ) .  网络编程(Udp-聊天)


10 ) .  网络编程(TCP-传输)


11 ) .   网络编程(TCP-练习)


 

     一 .   网络编程(概述)

1 ) . 简述  :网络通讯要素详解, IP地址的发展, 端口号的区分,以及常用的传输协议

1.1 网络模型

[1] OSI参考模型

[2] TCP/IP参考模型

1.2 网络通讯要素 

[1] IP地址

[2] 端口号

[3] 传输协议



1.3 图解通讯方式 : 




2 ) . 理解 : 

2.1 IP地址  -->如同你的快递明确的送货地址    -->指唯一标识位置

2.2 端口 :  -->如送你的快递明确的收货人手机号  --> 指唯一标识人

2.3 协议:  --> 如送你的快递明确的收获方式,双方都得知道  -->指相互约定好的规则

3 ) .  物理端口与逻辑端口的区别?

3.1 物理端口是看到的摸得着的端口,例 : 网线接口

3.2 逻辑端口是虚拟的端口,例如 QQ程序

4 ). 数据传输软件(QQ)的流程?

4.1 寻找对方计算机IP

4.2 寻找对方应用程序上的逻辑端口  -->端口是网络应用程序通过数字对自己进行表示的方式

4.3 判断通讯规则是否为同一协议  --> 国际组织定义了通用协议

TCP/IP ,是通讯的规则



5 ) . IP地址(四段)的发展  --.>子网掩码的出现  --> IP地址(六段) :

5.1 当计算机越来越普及的时候,IP不够用了,为了解决此问题,根据一个区域只给一个IP, 这个IP就是子网掩码

5.2 再到后来IP又不够用了,于是出现了IPV6 ,也就是 6段的IP地址

小结 : 区域子网掩码(区域IP) --> 个人IP地址

6 ) .  IP(四段)与IP(六段)的区别?

6.1 ipV4 的地址都是数字,而ipV6不仅包含数字还包含字母

7 ) . 端口号的区分 : 

7.1 0-1024的端口号被系统所保留,用来给相关应用程序

7.2 0-65535 的端口号 随意选择,只是  0-1024端口号尽量别用,留给系统分配

8 ). 常用端口号:

8.1 web : 80

8.2 Tomcat : 8080

8.3 mySql : 3306

9 ). 常用的传输协议

9.1 TCP/IP

9.2 UDP

10 ) . 心得 : 

10.1  网络编程是 单机版 --> 网络版的递进

10.2 数据通讯的原理就是数据传输

10.3 主机地址(IP地址)是一个计算机在互联网 上的唯一标识

10.4 当我们双方没有同一协议时,是不能完成通讯的,有些机密组织有自己的通讯协议



 
小结 :  

           1.  IP地址 --> 端口号 -->协议 

           2.  IP地址分为四段,每一段的最大值是255
        
           3.  特殊的IP地址 : 本地回环地址 : 127.0.0.1 ,可以用来在dos窗口内输入 ping 127.0.0.1 看反馈来 测试网卡,若拼通则正常

           4. 局域网中会出现IP冲突的问题,而广域网则不会

           5.  但凡是应用程序,都需要有数字标识,这数字标识就是端口号
        
  

       二.    网络编程(网络模型)


1 ) . OIS模型图解 :


2 )  TCP/IP图解:


 

3 ) . 相关常见协议 :

3.1 应用层协议 : 

[1] HTTP (Hyper Text Transfer Protocol) :   超文本传输协议

[2] HTTPS (Hyper Text Transfer Protocol) 超文本传输协议安全

[3] FTP (File Transfer Protocol) : 文件传输协议

[4] NFS  (Network File System):  网络文件系统

[5] SMTP  (Simple Message Transfer Protocol) ; 简单邮件传输协议

3.2 传输层协议 :

[1] TCP (Transmission Control Protocol) : 传输控制协议

[2] UDP (User Datagram Protocol) : 用户数据报协议

[3] SPX  (Sequenced Packet Exchange protocol): 序列分组交换协议

3.3 网际层协议

[1] IP (Internet Protocol)   互联网协议

[2] IPX (Internet Packet eXchange): 以太网所用协议之一

 

小结 :  

           1.  无论是OSI模型还是TCP/IP模型,每个层次都有自己的协议,也就是通讯规则  
        



      三.  网络编程(IP地址)

1 ) . 复习网络通讯要素:

1.1 IP地址 : 

[1] 网络中设备的标识

[2] 不易记忆,可用主机名

[3] 本地回环地址: 127.0.0.1  主机名: localhost 

1.2 端口号 : 

[1] 用于标识进程的逻辑地址,不同进程的标识

[2] 有效端口 : 0~65535 ,其中0~1-024系统使用或保留端口

1.3 传输协议:

[1] 通讯的规则

[2] 常见协议 : TCP,UDP


2 ) . IP地址解析 : 

例子 : www.baidu.com   -->  www 属于万维网组织  ,  baidu 属于 自定义企业标识名称 ,  com  ,属于该企业的类型  ,com属于商业服务的类型

3 ) .  Demo:

/*
 
 
 
 本章讲述 :
 
 
 [1] InetAddress.getLocalHost();  : 此静态方法可实例化IP的对象
 
 [2] getHostAddress() :  获取本机地址
 
 [3] getHostName()  ;  获取本机地址名称
 
 [4] InetAddress.getByName("10.1.4.79");  通过IP获取其IP地址和主机名称
 
 
 小结;  先有对象,而后对象调方法
 
 */
 
 
 import java.net .*;
   class IpDemo
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws UnknownHostException
       {
                    
 
       /*     InetAddress lhost = InetAddress.getLocalHost();  //实例化一个IP地址对象
             
             String ipAdress = lhost.getHostAddress() ;  //获取本机地址
             
             String ipName =lhost.getHostName() ;   //获取本机地址名称
 
              sop(ipName.toString()+":"+ipAdress.toString());   //输出本机名称和地址IP */
             
             
              //---------------通过IP地址获取任意主机IP对应的名称
 
/*           InetAddress ipName = InetAddress.getByName("10.1.4.79");   //通过IP获取地址名称和主机名称
               sop(ipName.getHostAddress());  
               sop(ipName.getHostName());  
 */
               InetAddress ipName = InetAddress.getByName(" www.baidu.com" ;);   //通过名称获取IP地址和主机名称
               sop(ipName.getHostAddress());  
               sop(ipName.getHostName());  
             
             
             
             
             
       }
       
                           
                           
 
 
小结 :  

           1.  事务非常负责时可将其封装为对象以此简化,因为面向对象的特点是复杂程度简单化
        
           2.  一个IP有多个服务器地址 ,一个地址只能对应一个IP

           3. 网络编程的包:   java.net .*;

      

       

      四.  网络编程(TCP和UDP)

1 ) . 概念简述:、

1.1 UDP  : 面向无连接,是用户数据报协议

【1】 将数据及源和目的封装成数据包中,不需要建立连接

【2】 每个数据报的大小在限制在64K内

【3】因无连接,是不可靠协议

【4】不需要建立连接,因此速度快

1.2 TCP  :面向连接,是传输控制协议

【1】建立连接,形成传输数据的通道

【2】在连接中进行大数据量传输

【3】通过三次握手完成连接,是可靠协议

【4】必须建立连接,因此效率会低




2 ) . 相关案例:

2.1 UDP : 聊天软件,屏幕共享,网络视频会议

2.2 TCP :  下载软件,语音通话

2.3 可通过数据是否可不完整性来判断是UDP还是TCP,还可通过是否可不同步/同步的方式来判断是UDP还是TCP



3 ) .  UDP和TCP的区别:

3.1 UDP如同短信,TCP如同电话

3.2 UDP是异步的,TCP是需同步的

3.3 UDP是可丢数据的,TCP是不可丢数据的

3.4 UDP是高效传输的,TCP是低效完整传输的

3.5 TCP内部是需要三次握手协议的,UDP是不需要的

 
小结 :  

           1.  UDP如如同古时的写信,TCP如同现代的线上线下物流体系
        
           2.  三次握手协议是 ,一次请求,两次反馈

     

     五 .   网络编程(Socket)

1 ) . 简述 : 

1.1 Socket就是为网络服务提供的一种机制

1.2 通信的两端都有Socket

1.3 网络通信其实就是Socket间的通信

1.4 数据在两个Socket见通过IO传输

 
小结 :  

           1.  所谓的网络编程就是Socket(插座)编程
        
           2.  370的插座能插370针脚的CPU

           3. socket通讯也可形象说是两个码头间的通讯,依靠(IO)船只进行货物(数据)的传输

           4. 
 

       六.    网络编程(Udp-发送端)


1 ) . Demo:

/*
 
 
 
 本章讲述 :  通过udp传输方式,将一段文字数据发送出去
 
 思路:
 
 1.建立udpsocket服务
 2.提供数据,并将数据封装到数据包中
 3.通过socket服务的发送功能,将数据包发送出去
 4.关闭资源
 
 
 
 */
 
 
 import java.net .*;
   class UdpSend
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       {
                    
             //1.创建udp服务,通过DatagramSocket对象
             DatagramSocket ds =new     DatagramSocket();
             
             
             //2.确定数据,并封装成数据包 ; DatagramPaket(byte[] buf,int length,InetAdress adress ,int port)
             byte[] buf ="udp go me lai le".getBytes(); 
                    
                    
             DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),1000);
 
             //3.通过socket服务,将已有的数据包发送出去,通过send方法
             ds.send(dp);
             
             //4.关闭资源
             ds.close();
             
             
       }
       
                           
                           
             
      
   
     

2 ) . 流程 :  有服务,有数据,发送,而后关闭资源

 

小结 :  

           1.  码头于码头(Socket)之间输送货物,标准(TCP)是无损坏,方式(IO)是 船运,码头是socket,传输协议是 TCP /UDP , 传输方式是IO流
        
        


      七.    网络编程(Udp-接收端)

1 ) . Demo:


/*
 
 
 
 本章讲述 :  通过udp传输方式,将一段文字数据发送出去
 
 思路:
 
 1.建立udpsocket服务
 2.提供数据,并将数据封装到数据包中
 3.通过socket服务的发送功能,将数据包发送出去
 4.关闭资源
 
 
 方法:
 
 [1] DatagramSocket() :  初始化socket服务
 
 [2] DatagramPacket() ;  初始化数据包
 
 [3] send();   //数据发送方法
 
 
  
 
 */
 
 
 import java.net .*;
   class UdpSend
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       {
                    
             //1.创建udp服务,通过DatagramSocket对象
             DatagramSocket ds =new     DatagramSocket();
             
             
             //2.确定数据,并封装成数据包 ; DatagramPaket(byte[] buf,int length,InetAdress adress ,int port)
             byte[] buf ="udp go me lai le".getBytes(); 
                    
                    
             DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),10000);
 
             //3.通过socket服务,将已有的数据包发送出去,通过send方法
             ds.send(dp);
             
             //4.关闭资源
             ds.close();
             
             
       }
       
                           
                           
/*
需求 : 定义一个应用程序,用于接受UDP协议传输的数据并处理
思路:
1.定义udpSocket服务  -->通常会监听一个端口,其实就是给这个接受网络应用程序定义数字表示,方便于明确哪些数据过来该应用程序可以处理
2.定义一个数据包,因为要存储接收到的字节数据,因为数据包对象具有更多功能可提取字节数据中的不同数据信息
3.通过socket服务的receive方法可将收到的数据存入已定义好的数据包中
4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上
5.关闭资源
 
 方法:
 
 [1] DatagramSocket() :  初始化socket服务
 
 [2] DatagramPacket() ;  初始化数据包
 
 [3] receive();   //数据接收方法
 
 [4]getAddress(); 获取地址
 
 [5] getHostAddress();  获取主机地址
 
 [6] getData() ;  获取数据
 
*/
             
  class UdpReceive
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       {
             //1.创建udp socket,建立端点,并定义端口号
       DatagramSocket ds = new DatagramSocket(10000);
       
       while(true)  //在这里循环判定说明其接收服务一直开启
       {
       //2.定义数据包,欲用存储数据
       byte[] buf =new byte[1024];
       DatagramPacket dp =new DatagramPacket(buf,buf.length);
 
             //3.通过服务的receive方法将受到数据存入数据包中
             ds.receive(dp); //其是阻塞式方法,到这里定会停止
             
             //4通过数据包的方法获取其中的数据
             String reAdd = dp.getAddress().getHostAddress();
             
             int rePo = dp.getPort();
 
             String str =new String(dp.getData(),0,dp.getLength());
       
             sop(reAdd+":::"+str+":::"+rePo);
             
             
             
       }
       
             //5.关闭资源
             //ds.close();  //关闭,是因为让服务一直开启
             
       }
  }    
   

     
     
     

 

小结 :  

           1.  发送端可采用随机端口号,但接收端一定得自定义端口号,不然数据不知发哪去
        
           2.  一个发送端一个接收端,这是两个程序,需要开两个cmd程序

     

     八 网络编程(Udp-键盘录入方式数据)

1 ) . Demo:

/*
 
 本文讲述 :
 
 一个接收端接收.一个发送端发送,不断发送,不断接收
  
  
   [1] IO流
  
   [2] sorcket服务
 
 */
 
 
 import java.net .*;
 import java.io.*;
 //发送端
   class UdpSend2
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       {
             DatagramSocket ds =new DatagramSocket();
             
             BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
             
             String line=null;
             
             while((line=br.readLine())!=null)
             {
                    if(line.equals("886"))
                           break;
                    
                    byte[] buf =line.getBytes();
                    
                    DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.152.1"),1000);
                    
                    
                    ds.send(dp);
                    
             }
             
             ds.close();
             
                    
       }
          
  }
       //接收端
  class UdpReceive2
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       {
             DatagramSocket ds =new DatagramSocket(1000);
             
             while(true)
             {
             byte[] buf =new byte[1024];
             
              DatagramPacket dp =new DatagramPacket(buf,buf.length);
             
             ds.receive(dp);
             
             String adre = dp.getAddress().getHostAddress(); 
             
             String str =new String(dp.getData(),0,dp.getLength());
             
             sop(adre+"::"+str);
 
             
             }
             
             
             
       }
 
  }    
   
     

 
 
小结 :  

           1.  一个网段里边有两个端口不可用,一个是0 (网络地址),一个是255(广播地址) ,可通过广播实现群聊
        
       

     九 .   网络编程(Udp-聊天)

1 ) . Demo:

/*
 
 本文讲述 :
 
 需求 : 编写一个聊天程序 -->
 
 分析 : 有收数据的部分和发数据的部分,这两部分同时执行,因此用到多线程技术 ,一个线程专门用来收,一个线程专门用来发
 
 */
 
 
 import java.net .*;
 import java.io.*;
 import java.lang.*;
 
 //发送端
   class UdpSend implements Runnable 
  {    
       private DatagramSocket ds;
       
       
  public UdpSend(DatagramSocket ds)
  {
         this.ds =ds;
        
  }
 
  public void run()
  {
        
         try
         {
              
               BufferedReader br=new BufferedReader(new InputStreamReader(System.in));  //实例化一个键盘输入流
              
               String line=null;
 
              
               while((line=br.readLine())!=null) 
               {
                    if(line.equals("886"))
                           break;
                    
                    byte[] buf = line.getBytes();   //数据转化为Byte类型
        
                    DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.217.1"),1000);  //打包数据
                    
                    ds.send(dp);  //发送数据
                     
               }
 
              
         }
         catch(Exception e)
         {
               throw new RuntimeException("传输数据失败");
              
         }
        
  }
 
 
 
  }
       //接收端
  class UdpReceive implements Runnable
  {    
  private DatagramSocket ds;
       
       
  public UdpReceive(DatagramSocket ds)
  {
         this.ds =ds;
        
  }
   public void run()
  {
        
         try
         {
               while(true)
               {
                     
               byte[] buf =new byte[1024];  //定义临时存储容器
              
               DatagramPacket dp =new DatagramPacket(buf,buf.length);   //接收包
                    
                ds.receive(dp);  //数据放入接收包
              
                    String ad =  dp.getAddress().getHostAddress();    //获取其发送端的本地地址
                    
                    String str =new String(dp.getData(),0,dp.getLength());  //获取数据部分并转化为String类型
                    
                System.out.println(ad+"::"+str);
                     
               }
              
         }
        catch(Exception e)
         {
               throw new RuntimeException("传输数据失败");
              
         }
       
        
        
        
  }
  
 
  }    
 
 
    //主类
  class ChatDemo
  {    
       //输出方法
       public static void sop(Object obj)
       {
              System.out.println(obj);
             
       }
 
   //主方法
       public static void main(String args[])  throws Exception
       { 
 
             DatagramSocket sendSocket =new DatagramSocket();
             DatagramSocket receiveSocket =new DatagramSocket(1000);
             
           UdpSend us =new UdpSend(sendSocket);
       
             UdpReceive ur = new UdpReceive(receiveSocket);
             
             new Thread(us).start();
             
             new Thread(ur).start();
       
             
             
       }
 
  }    
     

 
小结 :  

           1.  聊天程序通过多线程的方式实现,一个线程掌控发数据,一个线程掌握接数据
        
     

       十.  网络编程(TCP-传输)


1 ) . 简述 : 

1.1 Socket和ServerSocket

1.2 建立客户端和服务端

1.3 建立连接后,通过Socket中的IO流进行数据的传输

1.4 关闭socket 

1.5 同样,TCP也可通过多线程实现客户端和服务端的两个独立的应用程序

2 ) . Demo:

/*
 
 本文讲述 :
 
 需求 :  演示TCP传输 ,客户端向服务端发送一条信息
 
 须知 : 1.TCP分客户端和服务端 ,客户端对应的对象是Socket,服务端对应的对象是ServerSocket
 
 
 
 */
 
 
 import java.net .*;
 import java.io.*;
 import java.lang.*;
 
  /*
  通过查阅Socket对象,发现在该对象建立时,就可以去连接指定主机,
 
  解析 : 因为TCP是面向连接的,因此在建立socket服务室,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输
 
  步骤:
 
  1.创建Socket服务,并指定要连接的主机和端口
 
  2. 获取socket服务中的输出流用来发送数据
 
  3. 关闭服务
 
  */
       //客户端
  class TcpSocket 
  {    
  //主方法
       public static void main(String args[])  throws Exception
       { 
 
   Socket sc =new Socket ("192.168.217.1",10000);  //初始化客户端的socket服务,并指定目的主机和端口
  
   OutputStream is = sc.getOutputStream();  //获取socket服务中的输出流用来发送数据
  
   is.write("TCPSocket to going".getBytes());  //向流内写入数据
  
   sc.close();  //关闭服务
  
    }
 
  }    
 
  /*
 
  需求 : 定义断点接收数据并打印在控制台上
 
  服务端:
  1.建立服务端的socket服务: ServerSocket();,并监听一个端口
  2.获取连接过来的客户端的对象 : 通过ServerSocket的accept的方法,没有连接便会等,因此这个方法是阻塞式的
  3.客户端若发来数据,那么服务端要使用对应的客户端的对象并获取到该客户端对象的读取流来读取发过来的数据并打印在控制台
  4.关闭服务端(可选)
 
 
 
  */
 //服务端
   class TcpServerSocket 
  { 
 
   //主方法
       public static void main(String args[])  throws Exception
       { 
 
 
       ServerSocket ss =new ServerSocket(10000);  //建立服务端的socket并监听一个端口
       
       Socket sc =   ss.accept();   //获取已连接过来的客户端的对象
       
       InputStream in = sc.getInputStream();  //获取其输入流来获取数据
       
       byte[] buf = new byte[1024];   //临时存储容器
       
       int len = in.read(buf);   //数据读出
       
       String ip = sc.getInetAddress().getHostAddress();  //获取其连接过来的客户端对象的IP地址
 
       System.out.println(ip+".......come");  //输出客户端地址
       
       System.out.println(new String(buf,0,len));  //输出发过来的数据
 
 
       sc.close();    //关闭客户端的资源
       ss.close();    //关闭服务端的资源
       } 
  }
 
  
     

 
4 .Demo:


/*
 
 本文讲述 : 演示TCP传输的客户端和服务端的互访
 
 需求 :  客户端给服务端发送数据,服务端收到后,给客户端反馈信息
 
 
 客户端:
 
 1.建立socker服务,指定要连接的主机和端口
 2.获取socket流中的输出流,将数据写到该流中
 3,获取socker流中的输入流,将服务端反馈的数据获取到,并打印
 4.关闭客户端资源
 
 */
 
 
 import java.net .*;
 import java.io.*;
 import java.lang.*;
  
       //客户端
  class TcpSocket 
  {    
 
       public static void main(String args[])  throws Exception
       { 
 
                    Socket s= new Socket("192.168.217.1",1000);  //初始化客户端对象,并指定主机地址和端口
                    OutputStream ou= s.getOutputStream();   //获取输出流输出数据
                    
                    ou.write("服务端的哥们,你好".getBytes());
                    
                    InputStream is = s.getInputStream();      //获取输入流接受反馈的数据
                    
                    byte[] buf =new byte[1024];
                    
                    int len = is.read(buf);
                    
                    System.out.println(new String(buf,0,len));
                    
                    s.close();   //关闭资源
 
    }
 
  }    
 
 
 //服务端
   class TcpServerSocket 
  { 
 
  
       public static void main(String args[])  throws Exception
       { 
 
             ServerSocket ss = new ServerSocket(1000);   //初始化服务端对象,并指定连接的端口
             
             Socket s = ss.accept();   //进行连接获取其连接对象
             
             InputStream is  = s.getInputStream();  //获取其连接对象的输入流,用来输出数据
             
             String ssAdd = s.getLocalAddress().getHostAddress();  //获取其连接对象的地址
             
             System.out.println(ssAdd+"......come");
             
             byte[] buf =new byte[1024];  
             
             int len =is.read(buf);
             
             System.out.println(new String(buf,0,len));  
             
             
             OutputStream ou = s.getOutputStream();   //获取其连接对象的输出流,用来反馈数据
       
             Thread.sleep(1000);  //测试: 等待
             ou.write("客户端,你好,俺服务端收到了".getBytes());  //写入反馈数据
             
             s.close();   //关闭客户端资源
             ss.close();  //关闭服务端资源
             
             
              
       } 
  }
 
  
     

 

4 ) .UDP与TCP

4.1 UDP有发送端和接收端  ,使用同一个类 DatagramSocket ,分不同的方法使用

4.2 TCP有客户端和服务端,使用两个类Socket和ServerSocket区分使用


小结 :  

           1.  UDP与TCP最大的不同就是 UDP是面向无连接,而TCP是面向连接,因而导致的方法使用的不同

  2. 客户端与服务端的对话要求  :  1. 有俩端口 2. 客户端有输出流输出数据,有输入流获取反馈数据 ;  服务端有输入流接受数据,有输出流反馈数据
        
        
 
      十一.    网络编程(TCP-练习)

1 ) . Demo:完整版  -->做一个文本转换服务器


/*
 
 本文讲述 :    完整版
 
 [1]开发常用对象
 
 [2]TCP常见问题
 
 需求 : 建立一个文本转换服务器
 描述 : 客户端给服务器发送文本,服务器会将文本转成大写返回客户端,而且客户端可不断地进行文本转换,当客户端输入ver时,转换结束
 
 分析:
 客户端: 既然是操作设备上的数据,那么就可以用到IO技术,并按照IO的操作规律来思考
 源:键盘录入
 目的:网络设备,网络输出流
 操作的是文本数据,因此可选字符流,想提高效率,又可加入缓冲
 
 步骤:
 1.建立服务
 2.获取键盘录入
 3.将数据发送给服务端
 4.服务端接受数据之后返回大写数据
 5.结束,关资源
 
 
 服务端:
 源:socket读取流
 目的:socket输出流
 都是文本,装饰;
 
 
 
 总结 :
 
 现象:客户端和服务端都在莫名的等待的原因?
 
 因为客户端和服务端都有阻塞式方法,这些方法没有读到结束标记,就会一直等,从而导致两端都等待
 
 */
 
 
 import java.io.*;
 import java.net .*;
  
       //客户端
  class TcpSocket 
  {    
 
       public static void main(String args[])  throws Exception
       { 
             //定义客户端端口
             Socket sk =new Socket("192.168.217.1",1000);
             //定义读取键盘数据的流对象
             BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
             //定义目的,将数据写入到Socket输出流,发给服务端
             BufferedWriter bwOut =new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
             //定义一个socket读取流,读取服务端返回的大写信息
             BufferedReader brInt =new BufferedReader(new InputStreamReader(sk.getInputStream()));
 
             String line=null;
             
             while((line=br.readLine())!=null)
             {
                    if(line.equals("over"))
                           break;
 
                    bwOut.write(line);
                    bwOut.newLine();
                    bwOut.flush();
                    
                    
                    String str = brInt.readLine();
                    
                    System.out.println("TcpSocket:"+str);
                    
             }
             
             sk.close();
 
             
 
    }
 
  }    
 
 
 //服务端
   class TcpServerSocket 
  { 
 
  
       public static void main(String args[])  throws Exception
       { 
 
             ServerSocket ss =new ServerSocket(1000);
             
             Socket s = ss.accept();
             
             String Ad = s.getInetAddress().getHostAddress(); 
             
             System.out.println(Ad+"connect.........");
             
             //读取socket读取流中的数据
             BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));
             
             //目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端
             BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
             
             String line=null;
             
             while((line=br.readLine())!=null)
             {
             
                     bw.write(line.toUpperCase());
                     bw.newLine();   //字符流需要换行为结束符
                     bw.flush(); //字符流需要刷新才能刷出数据
                    
             }
             s.close();
             ss.close();
 
 
             
              
       } 
  }
 
  
     


2 ). Demo: 简约版  -->做一个文本转换服务器

/*
 
 本文讲述 : 
 
 
 需求 : 建立一个文本转换服务器  , 与上个功能一样,只是简化版
 
 替换:
 
 [1] PrintStream 替换了之前的
 
 BufferedWriter bwOut =new BufferedWriter(new OutputStreamWriter(sk.getOutputStream()));
       
       bwOut.newLine();
                    
                    bwOut.flush();
                    
                    
                    因为PrintStream类中的方法自带了刷新和换行因此不需要这些了
 
 */
 
 
 
 import java.io.*;
 import java.net .*;
  
       //客户端
  class TcpSocket 
  {    
 
       public static void main(String args[])  throws Exception
       { 
             //定义客户端端口
             Socket sk =new Socket("192.168.217.1",1000);
             //定义读取键盘数据的流对象
             BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
             //定义目的,将数据写入到Socket输出流,发给服务端
 
             PrintStream brOut =new PrintStream(sk.getOutputStream(),true);   //通过 printStream代替掉我们的手动刷新等共
 
             //定义一个socket读取流,读取服务端返回的大写信息
             BufferedReader brInt =new BufferedReader(new InputStreamReader(sk.getInputStream()));
 
             String line=null;
             
             while((line=br.readLine())!=null)
             {
                    if(line.equals("over"))
                           break;
 
                     brOut.println(line);
                    
                    String str = brInt.readLine();
                    
                    System.out.println("TcpSocket:"+str);
                    
             }
             
             sk.close();
 
             
 
    }
 
  }    
 
 
 //服务端
   class TcpServerSocket 
  { 
 
  
       public static void main(String args[])  throws Exception
       { 
 
             ServerSocket ss =new ServerSocket(1000);
             
             Socket s = ss.accept();
             
             String Ad = s.getInetAddress().getHostAddress(); 
             
             System.out.println(Ad+"connect.........");
             
             //读取socket读取流中的数据
             BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));
             
             //目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端
             PrintStream brOut =new PrintStream(s.getOutputStream(),true);
             
             String line=null;
             
             while((line=br.readLine())!=null)
             {
             
                     brOut.println(line.toUpperCase());
             
                    
             }
             s.close();
             ss.close();
 
 
             
              
       } 
  }
 
  
     





小结 :  客户端向服务端发送请求,服务端获取客户端对象并连接,接收客户端的数据,然后反馈给客户端数据

      
         

 
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值