0%

网络编程

网络编程

第三阶段

★★★第十九章 网络编程

InetAddress

  • InetAddress 用于表示 Internet Protocol(IP) 地址。

    public class InetAddress implements java.io.Serializable

  • InetAddress 的常用方法:

    1. public static InetAddress getLocalHost():获取本机的 InetAddress 对象。
    2. public static InetAddress getByName(String host):根据指定的主机名/域名获取 ip 地址对象。
    3. getHostName:获取 InetAddress 对象的主机名/域名。
    4. getHostAddress:获取 InetAddress 对象的地址。
    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
    29
    30
    package com.f.chapter21.inetaddress_;

    import java.net.InetAddress;
    import java.net.UnknownHostException;

    /**
    * @author fzy
    * @date 2023/7/14 11:56
    * 演示 InetAddress 类的使用
    */
    public class InetAddress_API {
    public static void main(String[] args) throws UnknownHostException {
    //1.`public static InetAddress getLocalHost()`:获取本机的 `InetAddress` 对象。
    InetAddress localHost = InetAddress.getLocalHost();
    System.out.println(localHost); //Running-Noob/192.168.177.1

    //2.`public static InetAddress getByName(String host)`:根据指定的主机名/域名获取 `ip` 地址对象。
    InetAddress host1 = InetAddress.getByName("Running-Noob");
    System.out.println(host1); //Running-Noob/192.168.177.1

    InetAddress host2 = InetAddress.getByName("www.baidu.com");
    System.out.println(host2); //www.baidu.com/112.80.248.76

    //3.`getHostName`:获取 `InetAddress` 对象的主机名/域名。
    System.out.println(host2.getHostName()); //www.baidu.com

    //4.`getHostAddress`:获取 `InetAddress` 对象的地址。
    System.out.println("IP地址:" + host2.getHostAddress()); //IP地址:112.80.248.76
    }
    }

Socket

  1. 套接字(Socket开发网络应用程序被广泛采用,以至于成为事实上的标准。
  2. 通信的两端都要有 Socket,是两台机器间通信的端点。
  3. 网络通信其实就是 Socket 间的通信。
  4. Socket允许程序把网络连接当成一个流,数据在两个 Socket 间通过IO传输
  5. 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端。
  • Socket 用于读写数据的方法:

    1. socket.getInputStream() -> 返回一个 InputStream 对象
    2. socket.getOutputStream() -> 返回一个 OutputStream 对象
    • 一个 Socket 对象只有一个 InputStream 对象和一个 OutputStream 对象

★★★TCP网络通信编程

★TCP字节流编程
  • 案例 1(用TCP字节流编程):

    1. 编写一个服务器端,和一个客户端。
    2. 服务器端在 9999 端口监听。
    3. 客户端连接到服务器端,发送 “hello, server“,然后退出。
    4. 服务器端接收到客户端发送的信息,输出,并退出。

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-notebook/img/Java/C19-1.jpg)

    • 服务端

      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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      package com.f.chapter21.socket_;

      import java.io.IOException;
      import java.io.InputStream;
      import java.net.ServerSocket;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 16:32
      * 服务端
      */
      public class SocketServer01 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.在本机的 9999 端口监听,等待连接
      // 这里要求本机没有其他服务在监听9999,否则抛异常
      // serverSocket可以通过 accept() 返回多个 Socket 对象[如果有多个客户端连接服务器]
      ServerSocket serverSocket = new ServerSocket(port);
      System.out.println("服务端在 " + port + " 端口进行监听,等待连接...");
      //2.当没有客户端连接 9999 端口时,程序会阻塞,等待连接。
      // 如果有客户端连接,则会返回一个 Socket 对象,该对象是服务端的 Socket 对象(在图中对应绿框内的socket)
      Socket socket = serverSocket.accept();
      //有客户端连接 9999 端口,服务端socket:Socket[addr=/192.168.177.1,port=49534,localport=9999]
      System.out.println("有客户端连接 " + port + " 端口,服务端socket:" + socket);
      //3.当有客户端连接 9999 端口后,服务端通过 socket.getInputStream()
      // 读取客户端写入到数据通道的数据,然后服务端对数据进行输出显示
      InputStream inputStream = socket.getInputStream();
      byte[] buf = new byte[1024];
      int readLen = 0;
      System.out.println("读取客户端的内容如下:");
      while ((readLen = inputStream.read(buf)) != -1) {
      System.out.print(new String(buf, 0, readLen));
      }
      System.out.println();
      System.out.println("读取完毕...");
      //4.关闭流对象、socket和serverSocket,避免资源浪费
      inputStream.close();
      socket.close();
      serverSocket.close();
      System.out.println("服务端退出...");
      }
      }
    • 客户端

      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
      29
      30
      package com.f.chapter21.socket_;

      import java.io.IOException;
      import java.io.OutputStream;
      import java.net.InetAddress;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 16:32
      * 客户端
      */
      public class SocketClient01 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.连接服务端(ip, 端口)
      // 如果连接成功,生成客户端的Socket对象(在图中对应红框内的socket)
      Socket socket = new Socket(InetAddress.getLocalHost(), port);
      //连接服务端成功!客户端Socket:Socket[addr=Running-Noob/192.168.177.1,port=9999,localport=49534]
      System.out.println("连接服务端成功!客户端Socket:" + socket);
      //2.当有了Socket对象后,就可以通过socket.getOutputStream
      // 得到和Socket对象关联的输出流对象,然后进行输出
      OutputStream outputStream = socket.getOutputStream();
      outputStream.write("hello, server".getBytes());
      //3.关闭流对象和socket,避免资源浪费
      outputStream.close();
      socket.close();
      System.out.println("客户端退出...");
      }
      }
  • 案例 2(用TCP字节流编程):

    1. 编写一个服务器端,和一个客户端。
    2. 服务器端在 9999 端口监听。
    3. 客户端连接到服务器端,发送 “hello, server“,并接收服务器端回发的 “hello, client“,再退出。
    4. 服务器端接收到客户端发送的信息,输出,并发送 “hello, client“,再退出。

    注意:为了让通信双方知晓对方发送的信息是否发送完毕,应该设置一个发送结束标记,用 socket.shutdownOutput(); 来设置。

    注意一旦 socket.shutdownOutput(); 了,则与 socket 相关联的 outputStream 流就不能够再向外写东西了,否则会报错,所以 socket.shutdownOutput(); 的位置和关socket输出流的位置要处理好,因为关socket输出流的时候会有写数据的操作。

    • 服务端

      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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      package com.f.chapter21.socket_;

      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.net.ServerSocket;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 20:39
      */
      public class SocketServer02 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.监听 9999 端口,如果监听到有客户端请求 9999 端口,
      // 就建立服务端的 Socket 对象
      ServerSocket serverSocket = new ServerSocket(port);
      Socket socket = serverSocket.accept();
      //2.建立和Socket对象相关联的输入输出流对象
      InputStream inputStream = socket.getInputStream();
      OutputStream outputStream = socket.getOutputStream();
      //3.读取客户端发送的消息
      byte[] buf = new byte[1024];
      int readLen = 0;
      while ((readLen = inputStream.read(buf)) != -1) {
      System.out.println(new String(buf, 0, readLen));
      }
      //4.发送消息到客户端,并设置结束标记
      outputStream.write("hello, client".getBytes());
      socket.shutdownOutput(); //设置结束标记
      //5.释放资源
      outputStream.close();
      inputStream.close();
      socket.close();
      serverSocket.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
      29
      30
      31
      32
      33
      34
      35
      package com.f.chapter21.socket_;

      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.net.InetAddress;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 20:39
      */
      public class SocketClient02 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.建立客户端的Socket对象
      Socket socket = new Socket(InetAddress.getLocalHost(), port);
      //2.建立和Socket对象相关联的输入输出流对象
      OutputStream outputStream = socket.getOutputStream();
      InputStream inputStream = socket.getInputStream();
      //3.发送消息到服务端,并设置结束标记
      outputStream.write("hello, server".getBytes());
      socket.shutdownOutput(); //设置结束标记
      //4.读取服务端发送的消息
      byte[] buf = new byte[1024];
      int readLen = 0;
      while ((readLen = inputStream.read(buf)) != -1) {
      System.out.println(new String(buf, 0, readLen));
      }
      //5.释放资源
      inputStream.close();
      outputStream.close();
      socket.close();
      }
      }
★TCP字符流编程
  • 案例 3(用TCP字符流编程):

    1. 编写一个服务器端,和一个客户端。
    2. 服务器端在 9999 端口监听。
    3. 客户端连接到服务器端,发送 “hello, server“,并接收服务器端回发的 “hello, client“,再退出。
    4. 服务器端接收到客户端发送的信息,输出,并发送 “hello, client“,再退出。
    • 在案例 2 的基础上使用转换流 InputStreamReaderOutputStreamWriter 即可。

      注意:在使用字符流编程时,记得**写入后要 flush **,否则数据不会写入数据通道。

    • 服务端

      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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      package com.f.chapter21.socket_;

      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 20:39
      */
      public class SocketServer03 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.监听 9999 端口,如果监听到有客户端请求 9999 端口,
      // 就建立服务端的 Socket 对象
      ServerSocket serverSocket = new ServerSocket(port);
      Socket socket = serverSocket.accept();
      //2.建立和Socket对象相关联的输入输出流对象
      InputStream inputStream = socket.getInputStream();
      OutputStream outputStream = socket.getOutputStream();
      //3.将TCP字节流编程转换为TCP字符流编程
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
      BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "gbk"));
      //4.读取客户端发送的消息
      String line = null;
      while ((line = bufferedReader.readLine()) != null) {
      System.out.println(line);
      }
      //5.发送消息到客户端,并设置结束标记
      bufferedWriter.write("hello, client");
      bufferedWriter.newLine();
      bufferedWriter.flush(); //如果使用的是字符流编程,则需要手动刷新,否则数据不会写入数据通道
      socket.shutdownOutput(); //设置结束标记
      //6.释放资源(后打开的先关闭)
      bufferedWriter.close();
      bufferedReader.close();
      socket.close();
      serverSocket.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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      package com.f.chapter21.socket_;

      import java.io.*;
      import java.net.InetAddress;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/14 20:39
      */
      public class SocketClient03 {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      //1.建立客户端的Socket对象
      Socket socket = new Socket(InetAddress.getLocalHost(), port);
      //2.建立和Socket对象相关联的输入输出流对象
      OutputStream outputStream = socket.getOutputStream();
      InputStream inputStream = socket.getInputStream();
      //3.将TCP字节流编程转换为TCP字符流编程
      BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "gbk"));
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
      //4.发送消息到服务端,并设置结束标记
      bufferedWriter.write("hello, server");
      bufferedWriter.newLine();
      bufferedWriter.flush(); //如果使用的是字符流编程,则需要手动刷新,否则数据不会写入数据通道
      socket.shutdownOutput(); //设置结束标记
      //5.读取服务端发送的消息
      String line = null;
      while ((line = bufferedReader.readLine()) != null) {
      System.out.println(line);
      }
      //6.释放资源(后打开的先关闭)
      bufferedReader.close();
      bufferedWriter.close();
      socket.close();
      }
      }
★网络上传文件
  • 案例 4:

    1. 编写一个服务端,和一个客户端。
    2. 服务器端在 9999 端口监听。
    3. 客户端连接到服务端,发送一张图片 hello.jpg
    4. 服务器端接收到客户端发送的图片,保存到 src 下,发送 “收到图片” 再退出。
    5. 客户端接收到服务端发送的 “收到图片”,再退出。
    6. 该程序要求使用 StreamUtils.java(一个自己编写的流处理工具类)。
    • 注意:文件一开始是在磁盘上的,所以要先把文件从磁盘读到程序内存中,然后再进行服务端和客户端之间的传输

    • 服务端

      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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      package com.f.chapter21.socket_;

      import java.io.*;
      import java.net.ServerSocket;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/15 13:22
      * 文件传输的服务端
      */
      public class FileDownloadServer {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      String savePath = "file\\copy.jpg"; //文件保存的位置
      //1.得到服务端的Socket对象
      ServerSocket serverSocket = new ServerSocket(port);
      System.out.println("服务端正在 " + port + " 端口监听...");
      Socket socket = serverSocket.accept();
      //2.得到Socket对象相关联的输入输出流,用于数据的传输
      InputStream socketInputStream = socket.getInputStream();
      OutputStream socketOutputStream = socket.getOutputStream();
      BufferedInputStream socketBufferedInputStream = new BufferedInputStream(socketInputStream);
      BufferedWriter socketBufferedWriter = new BufferedWriter(new OutputStreamWriter(socketOutputStream));
      //3.得到要保存的文件的输出流
      BufferedOutputStream fileBufferedOutputStream = new BufferedOutputStream(new FileOutputStream(savePath));
      //4.服务端从客户端接收数据,并将数据写入到保存文件中
      byte[] fileBytes = StreamUtils.streamToByteArray(socketBufferedInputStream); //文件对应的字节数组
      fileBufferedOutputStream.write(fileBytes);
      //5.服务端将消息发送给客户端
      socketBufferedWriter.write("收到图片...");
      //如果没有flush将数据写入数据通道,则在socketBufferedWriter.close();时会报异常:
      // Cannot send after socket shutdown: socket write error
      // 因为数据还并没有写入到数据通道中
      socketBufferedWriter.flush();
      socket.shutdownOutput(); //设置结束标记
      //6.释放资源
      socketBufferedWriter.close();
      fileBufferedOutputStream.close();
      socketBufferedInputStream.close();
      socket.close();
      serverSocket.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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      package com.f.chapter21.socket_;

      import java.io.*;
      import java.net.InetAddress;
      import java.net.Socket;

      /**
      * @author fzy
      * @date 2023/7/15 13:21
      * 文件传输的客户端
      */
      public class FileUploadClient {
      public static void main(String[] args) throws IOException {
      int port = 9999;
      String srcFilePath = "C:\\Users\\1\\Doc\\入党相关\\会议背景.jpg";
      //1.得到客户端的Socket对象
      Socket socket = new Socket(InetAddress.getLocalHost(), port);
      //2.得到Socket对象相关联的输入输出流,用于数据的传输
      OutputStream socketOutputStream = socket.getOutputStream();
      InputStream socketInputStream = socket.getInputStream();
      BufferedOutputStream socketBufferedOutputStream = new BufferedOutputStream(socketOutputStream);
      BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(socketInputStream));
      //3.得到要发送的文件的输入流
      BufferedInputStream fileBufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
      //4.客户端将文件数据发送给服务端
      byte[] fileBytes = StreamUtils.streamToByteArray(fileBufferedInputStream); //文件对应的字节数组
      socketBufferedOutputStream.write(fileBytes);
      socket.shutdownOutput(); //设置结束标记
      //5.客户端从服务端接收“收到文件”的消息
      String line = null;
      while ((line = socketBufferedReader.readLine()) != null) {
      System.out.println(line);
      }
      //6.释放资源
      socketBufferedReader.close();
      socketBufferedOutputStream.close();
      fileBufferedInputStream.close();
      socket.close();
      }
      }
    • StreamUtils 工具类:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      package com.f.chapter21.socket_;

      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.io.InputStream;

      /**
      * @author fzy
      * @date 2023/7/15 14:20
      */
      public class StreamUtils {
      public static byte[] streamToByteArray(InputStream is) throws IOException {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] buf = new byte[1024];
      int readLen = 0;
      while ((readLen = is.read(buf)) != -1) {
      bos.write(buf, 0, readLen); //把读取到的数据写入bos
      }
      byte[] bytes = bos.toByteArray(); //将bos中的数据转换为字节数组
      bos.close();
      return bytes;
      }
      }

netstat

  • netstat -an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况。

    1. LISTENING 表示某个端口在监听。

    2. 如果有一个外部程序连接到该端口,就会显示一条连接信息,状态变为 ESTABLISHED

      当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是 TCP/IP 来分配的,是不确定的,是随机的。

UDP网络编程

  1. DatagramSocketDatagramPacket 实现了基于 UDP 协议网络程序。
  2. UDP 数据报 DatagramPacket 通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP 数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
  3. DatagramPacket 对象封装了 UDP 数据报,在数据报中包含了发送端的 IP 地址和端口号以及接收端的 IP 地址和端口号
  4. UDP 协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
  • 注意:

    1. UDP 没有明确的服务端和客户端,而是数据的发送端和接收端,而且数据的发送端和接收端是可能变化的。
    2. 接收数据和发送数据是通过 DatagramSocket 对象来完成的。
    3. 数据是封装在 DatagramPacket 对象中的,发送数据时要将数据 “装包” 成数据报,接收数据时要将数据报 “拆包” 成数据。

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-notebook/img/Java/C19-2.jpg)

  • 案例:

    1. 编写一个接收端 A 和一个发送端 B
    2. 接收端 A9999 端口等待接收数据(receive)。
    3. 发送端 B 向接收端 A 发送数据 “hello, 明天吃火锅~“。
    4. 接收端 A 接收到发送端 B 发送的数据,回复 “好的,明天见”,再退出。
    5. 发送端 B 接收回复的数据,再退出。
    • 发送端

      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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      package com.f.chapter21.udpsocket_;

      import java.io.IOException;
      import java.net.*;

      /**
      * @author fzy
      * @date 2023/7/16 14:54
      */

      public class UDPSenderB {
      public static void main(String[] args) throws IOException {
      //1.创建DatagramSocket对象,准备发送数据
      int port = 9998; //发送端和接收端的端口不要重复,该端口是该DatagramSocket对象接收数据时用的端口
      DatagramSocket sendSocket = new DatagramSocket(port);
      //2.将需要发送的数据封装到 DatagramPacket 对象中
      byte[] buf = "hello, 明天吃火锅~".getBytes();
      /*创建要发送的DatagramPacket对象时,传入的参数依次是:
      * buf:数据包数据。
      * offset:分组数据偏移量。
      * length:分组数据长度。
      * address:目的地址。
      * port:目的端口号。
      * */
      DatagramPacket sendPacket = new DatagramPacket(buf, 0, buf.length, InetAddress.getLocalHost(), 9999);
      //3.发送数据报
      sendSocket.send(sendPacket);
      //4.发送端接收接收端发送过来的消息
      byte[] receive = new byte[64 * 1024];
      DatagramPacket receivePacket = new DatagramPacket(receive, receive.length);
      sendSocket.receive(receivePacket);
      //5.对接收到的数据报进行拆包,取出其中的数据并显示
      System.out.println("接收到接收端的回复:");
      byte[] data = receivePacket.getData();
      int length = receivePacket.getLength();
      System.out.println(new String(data, 0, length));
      //System.out.println(receivePacket.getAddress()); //接收方的地址
      //System.out.println(receivePacket.getPort()); //接收方的端口
      //6.关闭资源
      sendSocket.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
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      package com.f.chapter21.udpsocket_;

      import java.io.IOException;
      import java.net.DatagramPacket;
      import java.net.DatagramSocket;

      /**
      * @author fzy
      * @date 2023/7/16 14:54
      */
      public class UDPReceiverA {
      public static void main(String[] args) throws IOException {
      //1.创建一个DatagramSocket对象,准备在 9999 端口接收数据
      int port = 9999;
      DatagramSocket receiveSocket = new DatagramSocket(port);
      //2.构建一个DatagramPacket对象,准备接收数据
      // UDP数据报的大小限制在64K内
      byte[] buf = new byte[64 * 1024];
      /*创建接收数据报的DatagramPacket对象时,传入的参数依次是:
      * buf - 用于保存传入数据报的缓冲区。
      * length - 要读取的字节数。
      * */
      //因为不知道对方发送过来的数据报的大小,所以传入的length参数为buf.length
      DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
      //3.调用接收方法,将通过网络传输的DatagramPacket对象填充到receivePacket中去
      System.out.println("接收端A等待接收数据...");
      receiveSocket.receive(receivePacket);
      //4.对receivePacket进行拆包,取出数据并显示
      int length = receivePacket.getLength(); //实际接收到的数据长度
      byte[] data = receivePacket.getData(); //接收到的数据
      System.out.println(new String(buf, 0, length));
      //System.out.println(receivePacket.getAddress()); //发送方的地址
      //System.out.println(receivePacket.getPort()); //发送方的端口
      //5.接收端向发送端回复消息
      byte[] response = "好的,明天见".getBytes();
      //receivePacket中含有发送端的IP地址和端口号
      DatagramPacket sendPacket = new DatagramPacket(response, 0, response.length, receivePacket.getAddress(), receivePacket.getPort());
      receiveSocket.send(sendPacket);
      //6.关闭资源
      receiveSocket.close();
      }
      }
---------------The End---------------