• 【网络通信三要素】TCP与UDP快速入门


    网络通信三要素

    1.什么是网络编程?

    可以让设备中的程序,与网络上其他设备中的程序进行数据交互,从而实现网络通信的手段,java.net.*包下提供了网络编程的解决方案

    2.基本的通信架构

    基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端),无论是CS架构,还是BS架构的软件都必须依赖网络编程
    在这里插入图片描述
    在这里插入图片描述

    3.网络通信三要素
    • IP:设备在网络中的地址,是唯一的标识

      IP(Internet Protocol),全称"互联网协议地址",也称"IP地址",是分配给上网设备的数字标签常见的IP分类为IPv4和IPv6

      IPv4是4个字节,32个bit位,点分十进制表示法;IPv6

      lIPv6:由128bit位(16个字节)组成,号称可以为地球每一粒沙子编号,IPv6分为8组,每组的每四位编码成一个十六进制位表示, 冒分十六进制表示法

      特殊的IP地址:127.0.0.1、localhost:代表本机IP,只会寻找当前所在的主机

      IP常用命令

      • ipconfig:查看本机IP地址
      • lping IP地址:检查网络是否连通

      InetAddress:该类对象代表ip地址

      InetAddress的常用方法如下:

      • public static InetAddress getLocalHost:获取本机IP,会以一个 InetAddress的对象返回
      • public static InetAddress getByName(String host):根据ip地址或者域名,返回一个 InetAddress对象
      • public String getHostName():获取ip地址对象对应的主机名
      • public String getHostAddress():获取ip地址对象中的ip地址信息
      • public boolean isReachable(int timeout):在指定毫秒内,判断主机与该ip对应的主机是否能连通
    • 端口:应用程序在设备中的唯一标识,用两个字节表示,范围是0到65535

      分类

      • 周知端口:0-1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)
      • 注册端口:1024-49151,分配给用户进程或某些应用程序
      • 动态端口:49152-65535,之所以被称为动态端口,49152-65535,一般不固定分配给某进程,而是动态分配

      注意:开发程序一般使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错

    • 协议:连接和数据在网络中的传输规则

      传输层有两个通信协议:UDP(User Datagram Protocol)用户数据包协议;TCP(Transmission Control Protocol)传输控制协议

      UDP协议

      (1)特点:面向无连接,不可靠通信,通信效率高

      (2)不事先建立连接,数据包包含自己的ip、程序端口、目的地ip、程序端口和数据(64k)等

      (3)发送方不管对方是否在线,数据在路上丢不丢失,接收方收到数据也无需接收返回确认

      (4)应用场景:语音通话、视频直播

      Java提供了java.net.DatagramSocket类,来实现UDP通信

      DatagramSocket:用于创建客户端、服务端

      • public DatagramSocket():创建客户端的Socket,系统会随机分配一个端口号
      • public DatagramSocket(int port):创建服务端的Socket对象,并指定端口号
      • public void send(DatagramPacket dp):发送数据包
      • public void receive(DatagramPacket p):使用数据包接收数据

      DatagramPacket:创建数据包

      • public DatagramPacket(byte[] buf,int length,InetAddress address,int port):创建发出去的数据包对象
      • public DatagramPacket(byte[] buf,int length):创建用来接收数据的数据包
      • public int getLength():获取数据包,实际接收到的字节个数

      客户端:

      import java.net.*;
      
      public class UDPClient {
          public static void main(String[] args) throws Exception {
             
              //创建客户端Socket对象,随机分配端口号
              DatagramSocket client = new DatagramSocket(); //也可以指定
              //public DatagramPacket(字节数组, 数组长度, 服务器IP对象, 服务器端口号); 创建发送的数据包对象
              byte[] bytes = "礼物".getBytes();
              DatagramPacket dp = new DatagramPacket(
                      bytes,
                      bytes.length,
                      //InetAddress.getLocalHost(),
                      InetAddress.getByName("127.0.0.1"),
                      10000
      
              );
              //public void send(DatagramPacket dp); 发送数据包
              client.send(dp);
              //释放资源
              client.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

      服务端:

      import java.io.IOException;
      import java.net.*;
      
      public class UDPServer {
          public static void main(String[] args) throws Exception {
              System.out.println("UDP服务端启动,等待接收数据:");
      
              //创建服务器Socket对象,并指定端口号
              DatagramSocket server = new DatagramSocket(10000);
      
              //创建用来接收的数据包对象
              byte[] bytes = new byte[1024];
              DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
      
              //使用数据包接收数据
              server.receive(dp); //receive是阻塞的,等着接数据
      
              //展示数据
              int len = dp.getLength(); //len:代表本次接收的有效数据个数
              System.out.println(new String(bytes, 0, len));
      
              //DatagramPacket对象获取客户端其他信息
              System.out.println(dp.getAddress().getHostAddress());
              System.out.println(dp.getPort());
              //释放资源
              server.close();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28

    在这里插入图片描述

    TCP协议

    (1)特点:面向连接的,可靠通信,通信效率相对不高

    (2)TCP的最终目的,就是保证在不可靠的信道上,实现可靠的传输,传输数据不限制大小

    (3)TCP协议通过三次握手建立连接,通过四次挥手断开连接

    (4)应用场景:网页、文件下载、支付

    Java提供了一个java.net.Socket类来实现TCP通信

    • public Socket(String host,int port):根据指定二点服务器ip,端口号请求与服务端建立连接,连接通过就获得了客户端socket
    • public ServerSocket(int port):创建服务端ServerSocket对象并绑定端口号
    • public OutputStream getOutputStream():获得字节输出流对象
    • public InputStream getInputstream():获得字节输入流对象
    • public Socket accept():阻塞等待客户端的连接请求,一旦连接成功返回服务端Socket对象

    客户端:

    import java.io.DataOutputStream;
    import java.io.OutputStream;
    import java.net.DatagramSocket;
    import java.net.Socket;
    public class TCPClient {
        public static void main(String[] args) throws Exception {
           
            //根据指定的IP和端口创建客户端Socket对象
            Socket client = new Socket("127.0.0.1", 10010);
            //获取字节输出流对象(发送)
            OutputStream os = client.getOutputStream();
            //封装数据输出流
            DataOutputStream dos = new DataOutputStream(os);
            //写数据
            dos.writeUTF("发送礼物");
            //释放资源(释放new出来的资源)
            client.close();
            dos.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    服务端:

    import java.io.DataInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            System.out.println("TCP服务端启动,等待接收数据:");
            //创建服务端ServerSocket对象并绑定端口号
            ServerSocket server = new ServerSocket(10010);
            //阻塞等待客户端的连接请求,一旦连接成功返回服务端Socket对象
            Socket serverSocket = server.accept();
            //获取字节输入流对象(接收)
            InputStream is = serverSocket.getInputStream();
            //封装数据输入流
            DataInputStream dis = new DataInputStream(is);
            //读取数据
            System.out.println(dis.readUTF());
            //释放资源
            server.close();
            dis.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    注意:如果没有启动服务器,单独启动客户端,会报错 java.net.ConnectException

    原因:由于TCP是面向连接的,建立连接(三次握手)的时候失败

  • 相关阅读:
    Python数据分析与机器学习29-支持向量机(SVM)
    maven部署方案之分离业务包
    es(Elasticsearch)介绍
    springboot家乡特色推荐系统springboot28
    Spring框架注解大全
    软实力-领导力
    真正理解 Load Balance
    过去5年,PolarDB云原生数据库是如何进行性能优化的?
    驱动开发:内核字符串拷贝与比较
    基于springboot床上家纺用品网上销售系统的设计与实现-计算机毕业设计源码+LW文档
  • 原文地址:https://blog.csdn.net/m0_65462447/article/details/133524767