第十六章 网络编程

作者: 永不熄灭的火焰_e306 | 来源:发表于2019-12-01 15:22 被阅读0次

    网络编程

    一、InetAddress

    封装计算机的ip地址 ,没有端口。

     //使用getLocalHost方法创建InetAddress对象
     InetAddress addr = InetAddress.getLocalHost();
     System.out.println(addr.getHostAddress()); //返回:192.168.1.110
     System.out.println(addr.getHostName()); //输出计算机名
     ​
     //根据域名得到InetAddress对象
     addr = InetAddress.getByName(“www.163.com”); 
     System.out.println(addr.getHostAddress()); //返回 163服务器的ip:61.135.253.15  (因为咱们没有解析域名的权利,这个是由DNS来解析的)
     System.out.println(addr.getHostName()); //输出:www.163.com
     //根据ip得到InetAddress对象
     addr = InetAddress.getByName(“61.135.253.15”); 
     System.out.println(addr.getHostAddress()); //返回 163服务器的ip:61.135.253.15
     System.out.println(addr.getHostName()); //输出ip而不是域名。如果这个IP地 址不存在或DNS服务器不允许进行IP地址和域名的映射,getHostName方法就直接返回这个IP地
     址。
    

    二、InetSocketAddress

    包含端口,用于socket通信的

     //包含端口
     InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
     InetSocketAddress socketAddress2 = new InetSocketAddress(“localhost”,9000);
     System.out.println(socketAddress.getHostName());
     System.out.println(socketAddress2.getAddress());
    

    1 关于URI

    URI: Universal Resource Identifier 统一资源标志符,用
    来标识抽象或物理资源的一个紧凑字符串。
    • URL:Universal Resource Locator 统一资源定位符,一种定
    位资源的主要访问机制的字符串,一个标准的URL必须包括:
    protocol、host、port、path、parameter、anchor。
    • URN:Universal Resource Name 统一资源名称,通过特定命名
    空间中的唯一名称或ID来标识资源。</pre>

    http://www.google.com:80/index.html 由四部分组成

    协议 存放资源的主机域名 端口号 资源文件名

    关于URL
     URL u = new URL("http://www.baidu.con:80/index.html#aa?cansu=shsxt");
     System.out.println("获取与此url关联的协议的默认端口:
     "+u.getDefaultPort());
     System.out.println(“getFile:”+u.getFile()); //端口号后面的内容
     System.out.println("主机名:"+u.getHost()); //www.baidu.com
     System.out.println(“路径:”+u.getPath()); //端口号后,参数前的内容
     System.out.println(“端口:”+u.getPort()); //存在返回80.否则返回-1
     System.out.println("协议:"+u.getProtocol()); 
     System.out.println("参数部分:"+u.getQuery()); 
     System.out.println("锚点:"+u.getRef()); 
     URL u = new URL("http://www.abc.com/aa/");
     URL u2 = new URL(u,“2.html”); //相对路径构建url对象
     System.out.println(u2.toString()); //http://www.abc.com/aa/2.html
    
    相关API
    API.png

    三、传输协议 TCP、UDP

    1 UDP

    种无连接的传输层协议,提供面向事 务的简单不可靠信息传送服务

    特点

    非面向连接,传输不可靠,可能丢失

    发送不管对方是否准备好,接收方收 到也不确认

    可以广播发送

    非常简单的协议,开销小

    基本操作

     //接收方
     /**
      * 基本流程: 接收端
      * Address already in use: Cannot bind  同一个协议下端口不允许冲突
      * 1、使用DatagramSocket  指定端口 创建接收端
      * 2、准备容器 封装成DatagramPacket 包裹
      * 3、阻塞式接收包裹receive•(DatagramPacket p)
      * 4、分析数据
      *    byte[]  getData•()
      *                getLength•()
      * 5、释放资源
      * @author 裴新 QQ:3401997271
      *
      */
     public class UdpServer {
     ​
      public static void main(String[] args) throws Exception {
      System.out.println("接收方启动中.....");
      // 1、使用DatagramSocket  指定端口 创建接收端
      DatagramSocket server =new DatagramSocket(6666);
      // 2、准备容器 封装成DatagramPacket 包裹
      byte[] container =new byte[1024*60];
      DatagramPacket packet = new DatagramPacket(container,0,container.length);
      // 3、阻塞式接收包裹receive•(DatagramPacket p)
      server.receive(packet); //阻塞式
      // 4、分析数据
      //    byte[]  getData•()
      //                getLength•()
      byte[]  datas =packet.getData();
      int len = packet.getLength();
      System.out.println(new String(datas,0,len));
    
      // 5、释放资源
      server.close();
      }
     ​
     }
     //发送方
     /**
      * 基本流程: 发送端
      * 1、使用DatagramSocket  指定端口 创建发送端
      * 2、准备数据 一定转成字节数组
      * 3、 封装成DatagramPacket 包裹,需要指定目的地
      * 4、发送包裹send•(DatagramPacket p) * 
      * 5、释放资源
      * @author 裴新 QQ:3401997271
      *
      */
     public class UdpClient {
     ​
      public static void main(String[] args) throws Exception {
      System.out.println("发送方启动中.....");
      // 1、使用DatagramSocket  指定端口 创建发送端
      DatagramSocket client =new DatagramSocket(8888);
      //2、准备数据 一定转成字节数组
      String data = "上海尚学堂";
      byte[] datas = data.getBytes();
      //3、 封装成DatagramPacket 包裹,需要指定目的地
      DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
      new InetSocketAddress("localhost",6666));
      //4、发送包裹send•(DatagramPacket p) * 
      client.send(packet);
      // 5、释放资源
      client.close();
      }
     ​
     }
    

    文件传输

    //服务器端--接收端
     /**
      * 文件存储: 接收端
      * Address already in use: Cannot bind  同一个协议下端口不允许冲突
      * 1、使用DatagramSocket  指定端口 创建接收端
      * 2、准备容器 封装成DatagramPacket 包裹
      * 3、阻塞式接收包裹receive•(DatagramPacket p)
      * 4、分析数据    将字节数组还原为对应的类型
      *    byte[]  getData•()
      *                getLength•()
      * 5、释放资源
      * @author 裴新 QQ:3401997271
      *
      */
     public class UdpFileServer {
     ​
      public static void main(String[] args) throws Exception {
      System.out.println("接收方启动中.....");
      // 1、使用DatagramSocket  指定端口 创建接收端
      DatagramSocket server =new DatagramSocket(6666);
      // 2、准备容器 封装成DatagramPacket 包裹
      byte[] container =new byte[1024*60];
      DatagramPacket packet = new DatagramPacket(container,0,container.length);
      // 3、阻塞式接收包裹receive•(DatagramPacket p)
      server.receive(packet); //阻塞式
      // 4、分析数据    将字节数组还原为对应的类型
      //    byte[]  getData•()
      //                getLength•()
      byte[]  datas =packet.getData();
      int len = packet.getLength(); 
      IOUtils.byteArrayToFile(datas, "src/copy.png"); 
      // 5、释放资源
      server.close();
      }
     ​
     }
     ​
     //客户端--发送方
     /**
      *  文件上传: 发送端
      * 1、使用DatagramSocket  指定端口 创建发送端
      * 2、将基本类型  转成字节数组
      * 3、 封装成DatagramPacket 包裹,需要指定目的地
      * 4、发送包裹send•(DatagramPacket p) * 
      * 5、释放资源
      * @author 裴新 QQ:3401997271
      *
      */
     public class UdpFileClient {
     ​
      public static void main(String[] args) throws Exception {
      System.out.println("发送方启动中.....");
      // 1、使用DatagramSocket  指定端口 创建发送端
      DatagramSocket client =new DatagramSocket(8888);
      //2、准备数据 一定转成字节数组
      byte[] datas =IOUtils.fileToByteArray("src/logo.png"); 
      //3、 封装成DatagramPacket 包裹,需要指定目的地
      DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
      new InetSocketAddress("localhost",6666));
      //4、发送包裹send•(DatagramPacket p) * 
      client.send(packet);
      // 5、释放资源
      client.close();
      }
     ​
     }
    

    双方交流

     /**
      * 接收端: 使用面向对象封装
      * 
      * @author 裴新 QQ:3401997271
      *
      */
     public class TalkReceive implements Runnable {
      private DatagramSocket server ;
      private String from ;
      public TalkReceive(int port,String from) {
      this.from = from ;
      try {
      server=new DatagramSocket(port);
      } catch (SocketException e) {
      e.printStackTrace();
      }
      }
      @Override
      public void run() {
      while(true) {
      // 2、准备容器 封装成DatagramPacket 包裹
      byte[] container =new byte[1024*60];
      DatagramPacket packet = new DatagramPacket(container,0,container.length);
      // 3、阻塞式接收包裹receive•(DatagramPacket p)
      try {
      server.receive(packet);//阻塞式
      // 4、分析数据
      byte[]  datas =packet.getData();
      int len = packet.getLength();
      String data=new String(datas,0,len);
      System.out.println(from+":"+data);
      if(data.equals("bye")) {
      break;
      }
      } catch (IOException e) {
      e.printStackTrace();
      } 
      }
      // 5、释放资源
      server.close();
      }
     ​
     }
     ​
     /**
      * 发送端: 使用面向对象封装
      * 
      * @author 裴新 QQ:3401997271
      *
      */
     public class TalkSend implements Runnable {
      private DatagramSocket client ;
      private BufferedReader reader;
      private String toIP ;
      private int toPort ;
      public TalkSend(int port,String toIP,int toPort) {
      this.toIP = toIP;
      this.toPort=toPort;
      try {
      client=new DatagramSocket(port);
      reader =new BufferedReader(new InputStreamReader(System.in));
      } catch (SocketException e) {
      e.printStackTrace();
      }
      }
      @Override
      public void run() {
      while(true) {
      String data;
      try {
      data = reader.readLine();
      byte[] datas = data.getBytes();
      //3、 封装成DatagramPacket 包裹,需要指定目的地
      DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
      new InetSocketAddress(this.toIP,this.toPort));
      //4、发送包裹send•(DatagramPacket p) * 
      client.send(packet);
      if(data.equals("bye")) {
      break;
      }
      } catch (IOException e) {
      e.printStackTrace();
      }
    
      }
      // 5、释放资源
      client.close();
      }
     ​
     }
     ​
     //使用
     /**
      * 加入多线程,实现双向交流 模拟在线咨询
      * 
      * @author 裴新 QQ:3401997271
      *
      */
     public class TalkTeacher {
      public static void main(String[] args) {
      new Thread(new TalkReceive(9999,"学生")).start(); //接收
    
      new Thread(new TalkSend(5555,"localhost",8888)).start(); //发送
      }
     }
     -------------------------
     /**
      * 加入多线程,实现双向交流 模拟在线咨询
      * 
      * @author 裴新 QQ:3401997271
      *
      */
     public class TalkStudent {
      public static void main(String[] args) {
      new Thread(new TalkSend(7777,"localhost",9999)).start(); //发送 
      new Thread(new TalkReceive(8888,"老师")).start(); //接收
      }
     }
    

    2 TCP

    一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer) 通信协议。

    特点

    面向连接

    点到点的通信

    高可靠性

    占用系统资源多、效率低

    基本使用
    /**
      * 熟悉流程
      * 创建服务器
      * 1、指定端口 使用ServerSocket创建服务器
      * 2、阻塞式等待连接 accept
      * 3、操作: 输入输出流操作
      * 4、释放资源 
      * @author 裴新 QQ:3401997271
      *
      */
     public class Server {
     ​
      public static void main(String[] args) throws IOException {
      System.out.println("-----Server-----");
      // 1、指定端口 使用ServerSocket创建服务器
      ServerSocket server =new ServerSocket(8888);
      // 2、阻塞式等待连接 accept
      Socket  client =server.accept(); 
      System.out.println("一个客户端建立了连接");
      // 3、操作: 输入输出流操作
      DataInputStream dis =new DataInputStream(client.getInputStream());
      String data =dis.readUTF();
      System.out.println(data);
      // 4、释放资源 
      dis.close();
      client.close();
    
      server.close();
      }
     ​
     }
     ​
     /**
      * 熟悉流程
      * 创建客户端
      * 1、建立连接: 使用Socket创建客户端 +服务的地址和端口
      * 2、操作: 输入输出流操作
      * 3、释放资源 
      * @author 裴新 QQ:3401997271
      *
      */
     public class Client {
     ​
      public static void main(String[] args) throws UnknownHostException, IOException {
      System.out.println("-----Client-----");
      //1、建立连接: 使用Socket创建客户端 +服务的地址和端口
      Socket client =new Socket("localhost",8888);
      //2、操作: 输入输出流操作
      DataOutputStream dos =new DataOutputStream(client.getOutputStream());
      String data ="hello";
      dos.writeUTF(data);
      dos.flush();
      //3、释放资源 
      dos.close();
      client.close();
      }
     ​
     }
    
    多用户交互
     /**
      * 模拟登录 多个客户端请求
      * 创建服务器
      * 1、指定端口 使用ServerSocket创建服务器
      * 2、阻塞式等待连接 accept
      * 3、操作: 输入输出流操作
      * 4、释放资源 
      * @author 裴新 QQ:3401997271
      *
      */
     public class LoginMultiServer {
      public static void main(String[] args) throws IOException {
      System.out.println("-----Server-----");
      // 1、指定端口 使用ServerSocket创建服务器
      ServerSocket server =new ServerSocket(8888);
      boolean isRunning =true;;
      // 2、阻塞式等待连接 accept
      while(isRunning) {
      Socket  client =server.accept(); 
      System.out.println("一个客户端建立了连接");
      new Thread(new Channel(client)).start();
      }
      server.close();
      }
      //一个channel就代表一个客户端
      static class Channel implements Runnable{
      private Socket  client;
      //输入流
      private DataInputStream dis;
      //输出流
      private DataOutputStream dos;
      public Channel(Socket  client) {
      this.client = client;
      try {
      //输入
      dis = new DataInputStream(client.getInputStream());
      //输出
      dos =new DataOutputStream(client.getOutputStream()); 
      } catch (IOException e) {
      e.printStackTrace();
      release();
      }
    
      }
    
      //接收数据
      private String receive() {
      String datas ="";
      try {
      datas = dis.readUTF();
      } catch (IOException e) {
      e.printStackTrace();
      }
      return datas;
      }
      //释放资源
      private void release() {
      // 4、释放资源 
      try {
      if(null != dos) {
      dos.close(); 
      }
      } catch (IOException e) {
      e.printStackTrace();
      }
      try {
      if(null != dis) {
      dis.close();
      }
      } catch (IOException e) {
      e.printStackTrace();
      }
      try {
      if(null != client) {
      client.close();
      }
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      //发送数据
      private void send(String msg) {
      try {
      dos.writeUTF(msg);
      dos.flush();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      @Override
      public void run() { 
      // 3、操作: 输入输出流操作 
      String uname ="";
      String upwd ="";
      //分析
      String[] dataArray = receive().split("&");
      for(String info:dataArray) {
      String[] userInfo =info.split("=");
      if(userInfo[0].equals("uname")) {
      System.out.println("你的用户名为:"+userInfo[1]);
      uname = userInfo[1];
      }else if(userInfo[0].equals("upwd")) {
      System.out.println("你的密码为:"+userInfo[1]);
      upwd = userInfo[1];
      } 
      } 
      if(uname.equals("shsxt") && upwd.equals("laopei")) { //成功
      send("登录成功,欢迎回来");
      }else { //失败
      send("用户名或密码错误");
      }
    
      release();
    
      }
    
      }
    
     }
     /////////
     /**
      * 模拟登录  多个客户端请求
      * 创建客户端
      * 1、建立连接: 使用Socket创建客户端 +服务的地址和端口
      * 2、操作: 输入输出流操作
      * 3、释放资源 
      * @author 裴新 QQ:3401997271
      *
      */
     public class LoginMultiClient {
      public static void main(String[] args) throws UnknownHostException, IOException { 
      System.out.println("-----Client-----");
      //1、建立连接: 使用Socket创建客户端 +服务的地址和端口
      Socket client =new Socket("localhost",8888);
      //2、操作: 输入输出流操作  先请求后响应
      new Send(client).send();
      new Receive(client).receive(); 
      client.close();
      }
      //发送
      static class Send{
      private Socket client;
      private DataOutputStream dos;
      private BufferedReader console ;
      private String msg;
      public Send(Socket client) { 
      console=new BufferedReader(new InputStreamReader(System.in));
      this.msg =init();
      this.client = client;
      try {
      dos=new DataOutputStream(client.getOutputStream());
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      private String init() { 
      try {
      System.out.print("请输入用户名:");
      String uname =console.readLine();
      System.out.print("请输入密码:");
      String upwd =console.readLine();
      return "uname="+uname+"&"+"upwd="+upwd;
      } catch (IOException e) {
      e.printStackTrace();
      }
      return ""; 
      }
    
      public void send() {
      try {
      dos.writeUTF(msg);
      dos.flush();
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }
      //接收
      static class Receive{
      private Socket client;
      private DataInputStream dis;
      public Receive(Socket client) {
      this.client = client;
      try {
      dis=new DataInputStream(client.getInputStream());
      } catch (IOException e) {
      e.printStackTrace();
      }
      } 
      public void receive() {
      String result;
      try {
      result = dis.readUTF();
      System.out.println(result);
      } catch (IOException e) {
      e.printStackTrace();
      } 
    
      }
      }
     }
     ​
    

    相关文章

      网友评论

        本文标题:第十六章 网络编程

        本文链接:https://www.haomeiwen.com/subject/zqizwctx.html