Socket编程,TCP,UDP

1 IP和端口号 :

IP和端口号组成网络地址

IP(Internet Protocol),网络之间互连的协议,IP地址是区分不同计算机的唯一标识

端口号是计算机逻辑通讯接口,不同的应用程序用不同的端口,网络应用程序的区分标识

 // 2Byte =2B =16b       00000000  00000011   2

端口号一般使用2个字节(16bit 2的16次=65536)进行编号,最多可以有65536个端口,只有整数,范围是从0 到65535

第一类:公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议,例如:80端口实际上总是HTTP通讯。 21 ftp 22 ssh(security shell) 80 443 https …
https://www.qiansw.com/tcp-udp-port-list.html

第二类:注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。 3306 mysql 1433 sqlserver 1521 oracle 8080 tomcat 2181:2888:3888 zookeeper 8080 jenkins/tomcat redis 6379 mycat 8066 es 9092 …
第三类:动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口

2 TCP与UDP概念:

网络7层协议:物理层,数据链路层,网络层ip,传输层,会话层,表示层,应用层

传输层的两个主要协议

TCP(Transmission Control Protocol)协议:传输控制协议,提供可靠无差错的数据传输,保证数据正确性,速度慢,占用系统资源高,TCP面向连接。每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。

UDP(User Datagram Protocol)协议:用户数据报协议,不可靠的数据传输,可能丢包,速度快,占用资源较少,UDP面向无连接。UDP支持一对一,一对多,多对一和多对多的交互通信。

3 Socket编程原理(基于TCP)

服务器端
(1) 创建ServerSocket对象,绑定监听端口;
(2) 通过accept()方法监听客户端请求(产生阻塞);
(3) 连接建立后,通过输入流读取客户端发送的请求信息;
(4) 通过输出流向客户端发送相应信息;
(5) 关闭相应资源。

客户端
(1) 创建Socket对象,指明需要连接的服务器地址和端口;
(2) 连接建立后,通过输出流向服务器端发送请求信息;
(3) 通过输入流获取服务器端返回的响应信息;
(4) 关闭相应资源。

4 TCP具体代码实现:

简单示例:
服务器:

package com.aaa.tcp.demo1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 9:55
 * @ version:1.0.0
 */
public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter  = null;
        try {
            //        (1) 创建ServerSocket对象,绑定监听端口;
            serverSocket = new ServerSocket(16666);
            System.out.println("服务端已准备就绪,等待客户端连接。。。。");
            //        (2) 通过accept()方法监听客户端请求(产生阻塞);
            socket = serverSocket.accept();
            //        (3) 连接建立后,通过输入流读取客户端发送的请求信息;
                  //进行按行读取,提高效率,把字节流转换为字符流
                  //InputStreamReader 把字节流转字符流  BufferedReader在字符流套接缓存,提高读写效率
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                  //按行读取客户端信息信息
            String clientMsg = bufferedReader.readLine();
                  //打印
            System.out.println("客户端说:"+clientMsg);
            //        (4) 通过输出流向客户端发送相应信息;
                    //可以通过字符流按行输出信息
            printWriter  = new PrintWriter(socket.getOutputStream());
                    //写入信息
             printWriter.println("你好,客户端,收到了你的信息"+clientMsg+",给你回复!");
                    //刷新管道
            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (5) 关闭相应资源。
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(serverSocket!=null){
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

客户端

package com.aaa.tcp.demo1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
 * @ fileName:Client
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 10:35
 * @ version:1.0.0
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        try {
//        (1) 创建Socket对象,指明需要连接的服务器地址和端口;
            socket = new Socket("192.168.41.117",16666);
//        (2) 连接建立后,通过输出流向服务器端发送请求信息;
            printWriter = new PrintWriter(socket.getOutputStream());
               //写入消息
            printWriter.println("你好,服务器!");
               //刷新管道
            printWriter.flush();
//        (3) 通过输入流获取服务器端返回的响应信息;
            bufferedReader =
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));
               //按行读取信息
            String serverMsg = bufferedReader.readLine();
              //打印
            System.out.println("服务器说:"+serverMsg);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (4) 关闭相应资源。
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

模拟聊天:

 服务器:
package com.aaa.tcp.demo2;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 9:55
 * @ version:1.0.0
 */
public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter  = null;
        try {
            //        (1) 创建ServerSocket对象,绑定监听端口;
            serverSocket = new ServerSocket(16666);
            System.out.println("服务端已准备就绪,等待客户端连接。。。。");
            //        (2) 通过accept()方法监听客户端请求(产生阻塞);
            socket = serverSocket.accept();
            //        (3) 连接建立后,通过输入流读取客户端发送的请求信息;
                  //进行按行读取,提高效率,把字节流转换为字符流
                  //InputStreamReader 把字节流转字符流  BufferedReader在字符流套接缓存,提高读写效率
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //        (4) 通过输出流向客户端发送相应信息;
                    //可以通过字符流按行输出信息
            printWriter  = new PrintWriter(socket.getOutputStream());
             //实例化Scanner类,调用next方法,接受控制台输入
            Scanner scanner =new Scanner(System.in);
           while(true) {
               //按行读取客户端信息信息
               String clientMsg = bufferedReader.readLine();
               //打印
               System.out.println("客户端说:" + clientMsg);
               //判断退出循环
               if(clientMsg.contains("借钱")){
                   //写入信息
                   printWriter.println("你被拉黑了......");
                   //刷新管道
                   printWriter.flush();
                   break;//退出循环
               }
               //打印提示
               System.out.println("请输入:");
               //阻塞并等待控制台输入
               String serverInputMsg = scanner.next();
               //写入信息
               printWriter.println(serverInputMsg);
               //刷新管道
               printWriter.flush();
           }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (5) 关闭相应资源。
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(serverSocket!=null){
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

客户端:

package com.aaa.tcp.demo2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * @ fileName:Client
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 10:35
 * @ version:1.0.0
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        try {
//        (1) 创建Socket对象,指明需要连接的服务器地址和端口;
            socket = new Socket("192.168.41.117",16666);
//        (2) 连接建立后,通过输出流向服务器端发送请求信息;
            printWriter = new PrintWriter(socket.getOutputStream());
//        (3) 通过输入流获取服务器端返回的响应信息;
            bufferedReader =
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //实例化Scanner类,调用next方法,接受控制台输入
            Scanner scanner =new Scanner(System.in);
            while(true) {
                System.out.println("请输入:");
                String clientInputMsg = scanner.next();
                //写入消息
               printWriter.println(clientInputMsg);
               //刷新管道
               printWriter.flush();
               //按行读取信息
               String serverMsg = bufferedReader.readLine();
               //打印
               System.out.println("服务器说:" + serverMsg);
                //判断退出循环
                if(serverMsg.contains("拉黑")){
                    //写入信息
                    printWriter.println("别慌,拉黑前借钱");
                    //刷新管道
                    printWriter.flush();
                    break;//退出循环
                }
           }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (4) 关闭相应资源。
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

多线程:

服务器端:

 package com.aaa.tcp.demo3;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 11:13
 * @ version:1.0.0
 */
public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        try {
            //创建serverSocket服务端
            serverSocket = new ServerSocket(16666);
            while(true){
                System.out.println("服务端已经准备就绪,等待客户端连接。。。。");
                //等待客户端连接
                Socket socket = serverSocket.accept();
                //如果有客户连入,直接启动一个线程
                new Thread(new MTServer(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.aaa.tcp.demo3;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 9:55
 * @ version:1.0.0
 */
public class MTServer implements Runnable{
    private Socket socket;
    /**
     * 通过构造方法,给socket赋值
     * @param socket
     */
    public MTServer(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        System.out.println("客户端"+Thread.currentThread().getName()+"已经连接,可以对话!!!!");
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
            //        (3) 连接建立后,通过输入流读取客户端发送的请求信息;
            //进行按行读取,提高效率,把字节流转换为字符流
            //InputStreamReader 把字节流转字符流  BufferedReader在字符流套接缓存,提高读写效率
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //        (4) 通过输出流向客户端发送相应信息;
            //可以通过字符流按行输出信息
            printWriter = new PrintWriter(socket.getOutputStream());
            //实例化Scanner类,调用next方法,接受控制台输入
            Scanner scanner = new Scanner(System.in);
            while (true) {
                //按行读取客户端信息信息
                String clientMsg = bufferedReader.readLine();
                //打印
                System.out.println("客户端说:" + clientMsg);
                //判断退出循环
                if (clientMsg.contains("借钱")) {
                    //写入信息
                    printWriter.println("你被拉黑了......");
                    //刷新管道
                    printWriter.flush();
                    break;//退出循环
                }
                //打印提示
                System.out.println("请输入:");
                //阻塞并等待控制台输入
                String serverInputMsg = scanner.next();
                //写入信息
                printWriter.println(serverInputMsg);
                //刷新管道
                printWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (5) 关闭相应资源。
            if (printWriter != null) {
                printWriter.close();
            }
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /*public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter  = null;
        try {
            //        (1) 创建ServerSocket对象,绑定监听端口;
            serverSocket = new ServerSocket(16666);
            System.out.println("服务端已准备就绪,等待客户端连接。。。。");
            //        (2) 通过accept()方法监听客户端请求(产生阻塞);
            socket = serverSocket.accept();
            //        (3) 连接建立后,通过输入流读取客户端发送的请求信息;
                  //进行按行读取,提高效率,把字节流转换为字符流
                  //InputStreamReader 把字节流转字符流  BufferedReader在字符流套接缓存,提高读写效率
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //        (4) 通过输出流向客户端发送相应信息;
                    //可以通过字符流按行输出信息
            printWriter  = new PrintWriter(socket.getOutputStream());
             //实例化Scanner类,调用next方法,接受控制台输入
            Scanner scanner =new Scanner(System.in);
           while(true) {
               //按行读取客户端信息信息
               String clientMsg = bufferedReader.readLine();
               //打印
               System.out.println("客户端说:" + clientMsg);
               //判断退出循环
               if(clientMsg.contains("借钱")){
                   //写入信息
                   printWriter.println("你被拉黑了......");
                   //刷新管道
                   printWriter.flush();
                   break;//退出循环
               }
               //打印提示
               System.out.println("请输入:");
               //阻塞并等待控制台输入
               String serverInputMsg = scanner.next();
               //写入信息
               printWriter.println(serverInputMsg);
               //刷新管道
               printWriter.flush();
           }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (5) 关闭相应资源。
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(serverSocket!=null){
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }*/
}

客户端:


 package com.aaa.tcp.demo3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * @ fileName:Client
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 10:35
 * @ version:1.0.0
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        try {
//        (1) 创建Socket对象,指明需要连接的服务器地址和端口;
            socket = new Socket("192.168.41.117",16666);
//        (2) 连接建立后,通过输出流向服务器端发送请求信息;
            printWriter = new PrintWriter(socket.getOutputStream());
//        (3) 通过输入流获取服务器端返回的响应信息;
            bufferedReader =
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //实例化Scanner类,调用next方法,接受控制台输入
            Scanner scanner =new Scanner(System.in);
            while(true) {
                System.out.println("请输入:");
                String clientInputMsg = scanner.next();
                //写入消息
               printWriter.println(clientInputMsg);
               //刷新管道
               printWriter.flush();
               //按行读取信息
               String serverMsg = bufferedReader.readLine();
               //打印
               System.out.println("服务器说:" + serverMsg);
                //判断退出循环
                if(serverMsg.contains("拉黑")){
                    //写入信息
                    printWriter.println("别慌,拉黑前借钱");
                    //刷新管道
                    printWriter.flush();
                    break;//退出循环
                }
           }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //        (4) 关闭相应资源。
            try {
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(printWriter!=null){
                printWriter.close();
            }
            try {
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

5 UDP程序原理:

服务器端:
1) 创建服务端 DatagramSocket 类
2) 准备数据 以字节数组的形式
3) 打包 DatagramPacket+客户端的地址和端口
4) 发送
5) 释放资源
客户端
1) 创建客户端 DatagramSocket 类 + 指定的接收端口
2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
3) 包 接收数据
4) 分析 (组装字节数组)
5) 释放资源

6 UDP主要类及方法:

DatagramSocket类主要用于实现信息的发送和接收 。主要方法如下:

public DatagramSocket()
构造DatagramSocket对象,不指定监听的端口
public DatagramSocket(int port)
构造DatagramSocket对象,同时指定监听的端口
public void send (DatagramPacket p)
发送数据报
public void receive(DatagramPacket p)
接收数据报
DatagramPacket类用于包装需要发送或接收的信息
public DatagramPacket(byte[] buf,int length)
用来接收长度为 length 的数据包,length 参数必须小于等于 buf.length
public DatagramPacket(byte[]
buf,int length,InetAddress
address,int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号
public byte[] getData()
返回接收数据
public int getLength()
返回要发送或接收数据的长度

7 UDP具体代码实现:

示例代码:
服务器端:

package com.aaa.udp.demo1;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 11:35
 * @ version:1.0.0
 */
public class Server {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
//        1) 创建服务端 DatagramSocket 类
            datagramSocket = new DatagramSocket();
//        2) 准备数据 以字节数组的形式
            String  str = "hello client!";
            byte[] sendMsgBytes = str.getBytes();
//        3) 打包 DatagramPacket+客户端的地址和端口
               //参数1   发送消息的字节数组    参数2  发送消息字节数组长度  参数3  ip地址  参数4  端口号
            DatagramPacket datagramPacket =new DatagramPacket(sendMsgBytes,
                    sendMsgBytes.length,
                    InetAddress.getByName("localhost"),
                    18888);
//        4) 发送
            datagramSocket.send(datagramPacket);
            System.out.println("消息发送完毕。。。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //        5) 释放资源
            if(datagramSocket!=null) {
                datagramSocket.close();
            }
        }
    }
}

客户端:

package com.aaa.udp.demo1;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
 * @ fileName:Client
 * @ description:
 * @ author:zhz
 * @ createTime:2021/12/7 11:35
 * @ version:1.0.0
 */
public class Client {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
//        1) 创建客户端 DatagramSocket 类 + 指定的接收端口
            datagramSocket = new DatagramSocket(18888);
//        2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
            byte[] tempBytes =new byte[1024];
            DatagramPacket datagramPacket =new DatagramPacket(tempBytes,1024);
//        3) 包 接收数据  该方法会一致阻塞,直到收到信息
            System.out.println("客户端准备就绪,等待服务器发送消息。。。");
            datagramSocket.receive(datagramPacket);
//        4) 分析 (组装字节数组)
            //datagramPacket.getLength()  动态获取接收到信息的字节数组长度
            String receiveMsg = new String(tempBytes, 0, datagramPacket.getLength());
            System.out.println("收到信息:"+receiveMsg);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //        5) 释放资源
            if(datagramSocket!=null) {
                datagramSocket.close();
            }
        }
    }
}

注意事项:先启动客户端,receive方法在接收到数据报前一直阻塞。再运行服务器端。

8 UDP 对聊

客户端:

package com.aaa.udp.demo2;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
 * @ fileName:Client
 * @ description:
 * @ author:zhz
 * @ createTime:2021/5/10 11:27
 * @ version:1.0.0
 */
public class Client {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            //        1) 创建客户端 DatagramSocket 类 + 指定的接收端口
            datagramSocket = new DatagramSocket(8888);
            //实例化Scanner
            Scanner scanner = new Scanner(System.in);
            //        2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
            while (true) {
                //定义一个字节数组,作为缓冲容器,接受
                byte[] receiveBytes = new byte[2048];
                DatagramPacket datagramPacket = new DatagramPacket(receiveBytes, 2048);
                //        3) 包 接收数据  并记录接受数据的长度  长度由datagramPacket记录
                System.out.println("客户端准备完毕,等待服务端发送数据:");
                datagramSocket.receive(datagramPacket);
                //        4) 分析 (组装字节数组)
                String receiveStr = new String(receiveBytes, 0, datagramPacket.getLength());
                System.out.println("接受的数据为:" + receiveStr);
                if(receiveStr.contains("88")){
                    String sendMsg = "88";
                    //String  sendMsg = "您好,客户端,我是服务器端,测试数据发送。。。";
                    byte[] sendMsgByte = sendMsg.getBytes("UTF-8");
                    //        3) 打包 DatagramPacket+客户端的地址和端口
                    DatagramPacket datagramPacketClient = new DatagramPacket(sendMsgByte,sendMsgByte.length,
                            InetAddress.getByName("localhost"),7777);
                    //        4) 发送
                    datagramSocket.send(datagramPacketClient);
                    break;
                }
                System.out.println("请输入:");
                //        2) 准备数据 以字节数组的形式
                String sendMsg = scanner.next();
                //String  sendMsg = "您好,客户端,我是服务器端,测试数据发送。。。";
                byte[] sendMsgByte = sendMsg.getBytes("UTF-8");
                //        3) 打包 DatagramPacket+客户端的地址和端口
                DatagramPacket datagramPacketClient = new DatagramPacket(sendMsgByte,sendMsgByte.length,
                        InetAddress.getByName("localhost"),7777);
                //        4) 发送
                datagramSocket.send(datagramPacketClient);
                System.out.println("数据发送完毕。。。。。。。。。。。");
            }
            System.out.println("客户端端退出。。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //        5) 释放资源
            if(datagramSocket!=null){
                datagramSocket.close();
            }
        }
    }
}

服务端:

package com.aaa.udp.demo2;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
 * @ fileName:Server
 * @ description:
 * @ author:zhz
 * @ createTime:2021/5/10 11:27
 * @ version:1.0.0
 */
public class Server {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            //        1) 创建服务端 DatagramSocket 类 + 指定的发送端口
            datagramSocket = new DatagramSocket(7777);
               //实例化Scanner
            Scanner  scanner = new Scanner(System.in);
            while (true){
                System.out.println("请输入:");
                //        2) 准备数据 以字节数组的形式
                String sendMsg = scanner.next();
                //String  sendMsg = "您好,客户端,我是服务器端,测试数据发送。。。";
                byte[] sendMsgByte = sendMsg.getBytes("UTF-8");
                //        3) 打包 DatagramPacket+客户端的地址和端口
                DatagramPacket datagramPacket = new DatagramPacket(sendMsgByte,sendMsgByte.length,
                        InetAddress.getByName("localhost"),8888);
                //        4) 发送
                datagramSocket.send(datagramPacket);
                System.out.println("数据发送完毕。。。。。。。。。。。");
                //定义一个字节数组,作为缓冲容器,接受
                byte[] receiveBytes = new byte[2048];
                DatagramPacket datagramPacketServer = new DatagramPacket(receiveBytes, 2048);
                //        3) 包 接收数据  并记录接受数据的长度  长度由datagramPacket记录
                System.out.println("客户端准备完毕,等待服务端发送数据:");
                datagramSocket.receive(datagramPacketServer);
                //        4) 分析 (组装字节数组)
                String receiveStr = new String(receiveBytes, 0, datagramPacket.getLength());
                System.out.println("接受的数据为:" + receiveStr);
                 if(receiveStr.contains("88")){
                     break;
                 }
            }
            System.out.println("服务器端退出。。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //        5) 释放资源
            if(datagramSocket!=null){
                datagramSocket.close();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杵意

谢谢金主打赏呀!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值