前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >网络编程实操8小案例

网络编程实操8小案例

作者头像
用户9831583
发布2022-12-04 16:10:07
2720
发布2022-12-04 16:10:07
举报
文章被收录于专栏:码出名企路码出名企路

网络编程简介

/** * @brief * 网络编程 三大组件 * * 1, IP : 最大字节255, 默认得 127.0.0.1 ,ping不通网卡出问题了 * ipv4: 四段得ip, ipv6: 四段不够用了,定义了六段得 * 网络中设备得标识:不容易记忆,可用主机名,本地回环地址:127.0。0.1 主机名:localhost * * $ ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=1.39 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.029 ms * * 2,逻辑端口 0-65535 (0-1024被占用了,最好不用)web:8080 可以改 * * 3,通信规则 tcp/ip ,udp * * OSI参考模型 * TCP/IP参考模型 * $ javac Inet.java Command 'javac' not found, but can be installed with: sudo apt install openjdk-11-jdk-headless # version 11.0.15+10-0ubuntu0.20.04.1, or sudo apt install default-jdk # version 2:1.11-72 sudo apt install openjdk-16-jdk-headless # version 16.0.1+9-1~20.04 sudo apt install openjdk-17-jdk-headless # version 17.0.3+7-0ubuntu0.20.04.1 sudo apt install openjdk-8-jdk-headless # version 8u312-b07-0ubuntu1~20.04 sudo apt install openjdk-13-jdk-headless # version 13.0.7+5-0ubuntu1~20.04 sudo apt install ecj # version 3.16.0-1 * * $ uname -rs Linux 5.10.16.3-microsoft-standard-WSL2 $ cat /etc/issue Ubuntu 20.04.4 LTS \n \l * * UDP : 聊天,视频会议 * 1,将数据及源目的封装成数据包,不需要建立连接 * 2,每个数据包的大小限制在 64K 内 * 3,没有连接,因此是不可靠的 * 4,不需要建立连接,速度快 * * TCP:120打电话,下载 * 1,建立连接,形成传输数据的通道 * 2,在连接中进行大数据传输 * 3,通过三次握手完成连接,是可靠协议 * 4,必须建立连接,效率会低 * * Socket * 1,socket为网络服务提供一种机制 * 2,通信的两端都有socket * 3,网络通信其实就是socket间的通信 * 4,数据在两个socket间通过IO传输 */

UDP案例

案例1:UDP传输

Send端

代码语言:javascript
复制
//UDP传输 Send
class IPDemo
{
   public static void main(String[] args) throws Exception
   {
      //获取本机
      InetAddress i = InetAddress.getLocalHost();
      System.out.println(i.toString());
      System.out.println("address: "+i.getHostAddress());
      System.out.println("name: "+i.getHostName());

      //获取任意机器
      //不在同一网段,解析不出名字
      InetAddress ia = InetAddress.getByName("www.baidu.com");//www.baidu.com
      System.out.println(ia.toString());
      System.out.println("address: "+ia.getHostAddress());
      System.out.println("name: "+ia.getHostName());

      //UDP send
      /**
       * 思路:
       * 1,建立udpsocket服务
       * 2,提供数据,并将数据封装到数据包中
       * 3,通过socket服务的发生功能将数据包发出去
       * 4,关闭资源
       */
      //1, 创建 udp服务,通过 DatagramSocket对象
      DatagramSocket ds = new DatagramSocket();
      //2,确定数据,并封装成数据包
      byte[] buf = "udp ge men lai le".getBytes();
      DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("172.29.194.96"),10000);
      //3,通过socket服务,将已有的数据包发生出去,通过send方法
      ds.send(dp);
      //4, 关闭资源
      ds.close();
   }
}

Rece端

代码语言:javascript
复制
class IPRece
{
   public static void main(String[] args) throws Exception
   {
      
      //UDP rece
      //1, 创建 udp服务,建立端点,通常会监听一个端口
      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 ip = dp.getAddress().getHostAddress();
         String data = new String(dp.getData(),0,dp.getLength());
         int port = dp.getPort();
         System.out.println(ip+"::"+data+"::"+port);
      }
       //5,关闭资源
      //ds.close();
   }
}

案例2:键盘录入

Send端

代码语言:javascript
复制
//键盘录入
class UdpSend
{
   public static void main(String[] args) throws Exception
   {
      DatagramSocket ds = new DatagramSocket();

      BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

      String line = null;

      while((line = bufr.readLine()) != null)
      {
         if("886".equals(line))
            break;

         byte[] buf = line.getBytes();

         DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("172.29.194.96"),10001);

         ds.send(dp);
      }
      ds.close();
   }
}

Rece端

代码语言:javascript
复制
class UdpRece
{
   public static void main(String[] args) throws Exception
   {
      DatagramSocket ds =new DatagramSocket(10001);
      while(true)
      {
         byte[] buf = new byte[1024];
         DatagramPacket dp = new DatagramPacket(buf,buf.length);

         ds.receive(dp);
         String ip = dp.getAddress().getHostAddress();
         String data = new String(dp.getData(),0,dp.getLength());
         System.out.println(ip+"::"+data);
      }
   }
}

案例3:聊天系统

Send端 多线程定义:是个模板

代码语言:javascript
复制
class Send implements Runnable
{
   private DatagramSocket ds;
   public Send(DatagramSocket ds)
   {
      this.ds = ds;
   }
   
   public void run()
   {
      try 
      {
         DatagramSocket ds = new DatagramSocket();

         BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
   
         String line = null;
   
         while((line = bufr.readLine()) != null)
         {
            if("886".equals(line))
               break;
   
            byte[] buf = line.getBytes();
   
            DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("172.29.194.96"),10001);
   
            ds.send(dp);
        } 
      }
      catch (Exception e) 
      {
         throw new RuntimeException("send fail");
      }
   }
}

Rece端 多线程定义:是个模板

代码语言:javascript
复制
class Rece implements Runnable
{
   private DatagramSocket ds;
   public Rece(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 ip = dp.getAddress().getHostAddress();
            String data = new String(dp.getData(),0,dp.getLength());
            System.out.println(ip+"::"+data);
         }
         
      }
      catch (Exception e) 
      {
         throw new RuntimeException("rece fail");
      }
   }
}

调用

代码语言:javascript
复制
class ChatDemo
{
   public static void main(String[] args) throws Exception
   {
      DatagramSocket sendSocker = new DatagramSocket();
      DatagramSocket receSocker = new DatagramSocket(10001);

      new Thread(new Send(sendSocker)).start();
      new Thread(new Rece(receSocker)).start();
   }
}

TCP案例

案例1:基本传输

//TCP传输 /** * 客户端Socket和服务端ServerSocket * 建立客户端和服务器端 * 建立连接后,通过Socket中的IO 流进行数据的传输 * 关闭socket * 同样,客户端与服务端是两个独立的应用程序 */ /** * 客户端: 通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机 因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功 形成通路后,在该通道进行数据的传输 */

client

代码语言:javascript
复制
  class TcpClient
  {
      public static void main(String[] args) throws Exception
      {
         //创建客户端socket服务,指定目的主机和端口
         Socket s = new Socket("",10003);

         //为了发送数据,应该获取socket流中的输出流
         OutputStream out = s.getOutputStream();

         out.write("tcp ge men lai le".getBytes());

         //服务端返回信息
         InputStream in = s.getInputStream();
         byte[] buf = new byte[1024];
         int len = in.read(buf);
         System.out.println(new String(buf,0,len));

         s.close();
      }
  }

/** * 服务端: * 1,建立服务端的 socket服务,ServerSocket * 并监听一个端口 * 2,获取连接过来的客户端对象 * 通过 ServerSocket的accept方法,没有连续就会等,所以这个方法是阻塞的 * 3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到客户端对象的读取流来读取发过来的数据 * 4,关闭服务端 */

Server

代码语言:javascript
复制
  class TcpServer
  {
      public static void main(String[] args) throws Exception
      {
         //建立服务端 socket服务,并监听一个端口
         ServerSocket ss = new ServerSocket(10003);
         //通过accept方法获取连接过来的客户端对象
         Socket s = ss.accept();

         String ip = s.getInetAddress().getHostAddress();
         System.out.println(ip+"....connected");

         //获取客户端发送来的数据,使用客户端对象的读取来读取数据
         InputStream in = s.getInputStream();

         byte[] buf = new byte[1024];
         int len = in.read(buf);//阻塞的

         System.out.println(new String(buf,0,len));

         //给客户端反馈信息
         OutputStream out = s.getOutputStream();
         Thread.sleep(10000);
         out.write("rece !".getBytes());
         s.close();
         ss.close();
      }
  }

案例2:文本转换器

* * 建立一个文本转换器,客户端给服务端发送文本,服务端会将文本转成大写返回给客户端, * 而且客户端可以不断地进行文本转换,当客户端输入 over时,转换结束 * *步骤: 1,建立服务 2,获取键盘输入 3,将数据发送服务端 4,获取服务端返回地大写数据 5,结束,关资源 都是文本,用IO,提高效率 ,加入缓冲 */

client

代码语言:javascript
复制
class TransClient
{
   public static void main(String[] args) throws Exception
   {
      Socket s =new Socket("127.0.1.1",10006);

      //定义读取键盘数据地流对象
      BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

      //定义目的,将数据写入到 socket输出流,发送服务端
      BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

      //定义一个socket读取流,读取服务端返回地大写信息
      BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

      String line = null;
      while((line = bufr.readLine()) != null)
      {
         if("over".equals(line))
            break;

         bufOut.write(line);
         bufOut.newLine();//换行
         //数据写入缓冲区进行刷新
         bufOut.flush();



         String str = bufIn.readLine();
         System.out.println("server: "+str);
      }

      bufr.close();
      s.close();
   
   }
}

Server

代码语言:javascript
复制
class TransServer
{
   public static void main(String[] args) throws Exception
   {
      ServerSocket ss = new ServerSocket(10006);
      Socket s = ss.accept();

      String ip = s.getInetAddress().getHostAddress();
      System.out.println(ip+"....connected");

      //读取socket读取流中地数据
      BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

      //定义目的,socket输出流,将大写数据写入到 socket输出流,并发送给客户端
      BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
      
      //替换上面一行
      //PrintWrite out = new PrintWrite(s.getOutputStream,true);

      String line = null;
      while((line = bufIn.readLine()) != null)
      {  
         System.out.println(line);
         bufOut.write(line.toUpperCase());
         bufOut.newLine();//换行
         bufOut.flush();

         //替换上面三行
        // out.println(line.toUpperCase());
      }
      s.close();
      ss.close();
   
   }
}

/** * 出现问题: * 客户端和服务端都在莫名等待 * * 原因: * 因为客户端和服务端都有阻塞方法,这些方法没得读到结束标记,一直在等待,导致两端都在等待 */

案例3:图片传输

/** * 客户端: 1,服务端点 2,读取客户端已有的图片数据 3,通过 socket 输出流将数据发给服务端 4,读取服务端反馈信息 5,关闭 */

client

代码语言:javascript
复制
class PicClient
{
   public static void main(String[] args) throws Exception
   {  
      if (args.length != 1)
      {
         System.out.println("select one jpg img");
         return;
      }
      File file = new File(args[0]);
      if (!(file.exists() && file.isFile()))
      {
         System.out.println("file not ok");
         return;
      }
      if (!file.getName().endsWith(".jpg"))
      {
         System.out.print("geshi img not ok");
         return;
      }

      if (file.length() > 1024*1024*5)
      {
         System.out.println("big");
         return;
      }


      Socket s =new Socket("127.0.1.1",8003);
      FileInputStream fis = new FileInputStream(file);
      OutputStream out = s.getOutputStream();
      byte[] buf = new byte[1024];
      int len = 0;
      while((len = fis.read(buf)) != -1)
      {
         out.write(buf,0,len);
      }

      InputStream in = s.getInputStream();

      byte[] bufIn = new byte[1024];
      int num = in.read(bufIn);
      System.out.println(new String(bufIn,0,num));

      fis.close();
      s.close();
   }
}

/**服务端 * * 这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程 * 这是B客户端连接,只有等待。 * 因为服务端还没有处理完A客户端的请求,还有循环回来执行下次 accept方法,所以暂时 * 获取不到B客户端对象 * * 那么为了可以让多个客户端同时并发访问服务端 * 服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求 * 如何定义线程? * 只要明确了每一个客户端要在服务端执行的代码即可,将代码放入run中 */

代码语言:javascript
复制
class PicThread implements Runnable
{
   private Socket s;
   PicThread(Socket s)
   {
      this.s = s;
   }
   public void run()
   {
      int count = 1;
      String ip = s.getInetAddress().getHostAddress();
      try
      {
         System.out.println(ip+"...connected");
         InputStream in = s.getInputStream();
         File file = new File(ip+"("+(count)+")"+".jpg");
         while(file.exists())
            file = new File(ip+"("+(count++)+")"+".jpg");

         FileOutputStream fos = new FileOutputStream(file);
   
         byte[] buf = new byte[1024];
         int len = 0;
         while((len = in.read(buf)) != -1)
         {
            fos.write(buf,0,len);
         }
   
         OutputStream out = s.getOutputStream();
         out.write("upload sucess".getBytes());
         fos.close();
         s.close();
         
      }
      catch(Exception e)
      {
         System.out.println(ip+"...not connected");
      }
   }
}
class PicServer
{
   public static void main(String[] args) throws Exception
   {
      ServerSocket ss = new ServerSocket(8003);
      while(true)
      {  
         Socket s= ss.accept();
         
         new Thread(new PicThread(s)).start();
      }
    
      //ss.close();
   }
}

案例4:键盘录入

/*** * 需求分析: * 客户端通过键盘录入用户名 * 服务端对这个用户名进行校验 * * 如果该用户名存在,则在服务端显示XXX,已经登陆 * 并在客户端显示XXX 欢迎光临 * * 如果用户不存在,在服务端显示XXX,尝试登陆 * 并在客户端显示 XXX 该用户不存在 * * 最多就登录三次 */ client

代码语言:javascript
复制
class LoginClient
{
   public static void main(String[] args) throws Exception
   {
     Socket s = new Socket("172.23.236.114",107);
     BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
     PrintWriter out = new PrintWriter(s.getOutputStream(),true);
     BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));

     for(int x =0; x <3; x++)
     {
      String line = bufr.readLine();
      if(line == null)
         break;
      out.println(line);
      String info = bufIn.readLine();
    
      System.out.println("info:"+info);

      if(info.contains("欢迎"))
         break;
     }

     bufr.close();
     s.close();
   }
}

//服务端封装原理模板

代码语言:javascript
复制
//服务端封装原理模板
class UserThread implements Runnable
{
   private Socket s;
   UserThread(Socket s)
   {
      this.s = s;
   }
   public void run()
   {
      String ip = s.getInetAddress().getHostAddress();
      System.out.println(ip+"....connected");
      try
      {
         for(int x=0; x<3;x++)
         {
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String name = bufIn.readLine();
            System.out.println(name+"....name");
            if (name==null)
               break;
             
            BufferedReader bufr = new BufferedReader(new FileReader("2.txt.txt"));
       
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            String line =null;
        
            boolean flag = false;

            while((line=bufr.readLine()) != null)
            {
               if(line.equals(name))
               {
                  flag = true;
                  break;
               }
            }

            if(flag)
            {
               System.out.println(name+",已登录");
               out.println(name+",欢迎光临");
            }
            else
            {
               System.out.println(name+",尝试登录");
               out.println(name+",用户名不正确");
            }
         }
         s.close();
      }
      catch(Exception e)
      {
         System.out.println(ip+"...not connected");
      }
   }
}
class LoginServer
{
   public static void main(String[] args) throws Exception
   {
      ServerSocket ss = new ServerSocket(107);
      while(true)
      {
         Socket s= ss.accept();
         new Thread(new UserThread(s)).start();
      }
   }
}

案例5:浏览器客户端

/** * 客户端:浏览器 * 输入:https://172.23.236.114:11000/ * 或者终端输入:telnet 172.23.236.114 11000 * 服务端:自定义

*/

代码语言:javascript
复制
class ServerDemo
{
   public static void main(String[] args) throws Exception
   {
      ServerSocket ss = new ServerSocket(11000);
      Socket s =ss.accept();
      System.out.println(s.getInetAddress().getHostAddress());

      PrintWriter out = new PrintWriter(s.getOutputStream(),true);

      out.println("<font color='red' size='7'>客户端你好<.font>");
      s.close();
      ss.close();
   }
}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 网络编程简介
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档