Day27-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\Threadcase\ThreadPool+C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\IPDemo\UDPDemo-线程池和网络编程UDP

自定义线程池

image-20251031164343404

临时线程创建时机:当核心线程全都占用且等待队列中的数量已经超过设定的阈值的时候,才会触发创建临时线程

image-20251031164749071

image-20251031164857244

image-20251031164925435

package Basic.src.com.Threadcase.ThreadPool;

import java.util.concurrent.*;

public class MyThreadPoolDemo1 {
    public static void main(String[] args) {
        /*
        * (核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略)
        * 
        * 参数一:核心线程数量                不能小于0
        * 参数二:最大线程数                     不能小于等于0,最大数量>=核心线程数量
        * 参数三:空闲线程最大存活时间   不能小于0
        * 参数四:时间单位                          用 TimeUnit指定
        * 参数五:任务队列 (排队的客户)  不能为null
        * 参数六:创建线程工厂                   不能为null
        * 参数七:任务的拒绝策略             不能为null  
        * 
        * */

        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                3, 
                6,//最大线程数
                60,//空闲线程最大空闲时间
                TimeUnit.SECONDS,//时间单位
                new ArrayBlockingQueue<>(3),//任务队列,阻塞队列
                Executors.defaultThreadFactory(),//创建线程工厂
                new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略 
        );
        pool.submit(new MyRunnable());
    }
}

image-20251031170605959

网络编程

java.net.

通信架构

CS架构(客户端服务端)

image-20251031190011783

BS架构(浏览器服务端)

image-20251031190027464

网络编程三要素

  1. IP地址:设备在网络中的地址
  2. 端口号:应用程序在设备中唯一的标识
  3. 协议:连接和数据在网络中传输的规则

IP地址

互联网协议地址Internet Prototol

两种形式:IPv4(32位) IPv6

IPv4 地址 . . . . . . . . . . . . : 192.168.137.1

windows+R调出cmd,输入ipconfig回车

image-20251031190925048

IPv6地址 fe80::96de:391e:5aa7:6696%15

image-20251031191049550

IP域名

image-20251031192222203

  1. 重置网络协议:以管理员身份运行命令提示符,依次执行ipconfig /releaseipconfig /renewipconfig /flushdns,再重新测试ping 127.0.0.1

image-20251031192901786

InetAddress

代表IP地址

image-20251031193058079

package Basic.src.com.IPDemo;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressTest {
    public static void main(String[] args) throws IOException {
        //1.获取本机IP地址对象
        InetAddress ip1 = InetAddress.getLocalHost();
        System.out.println(ip1.getHostName());
        System.out.println(ip1.getHostAddress());//192.168.137.1
        InetAddress ip2 = InetAddress.getByName("www.baidu.com");
        System.out.println(ip2.getHostName());//www.baidu.com
        System.out.println(ip2.getHostAddress());//180.101.49.44  36.152.44.132

        //ping www.baidu.com
        System.out.println(ip2.isReachable(6000));
    }
}

端口号

标记在计算机设备上运行的应用程序,被规定为一个16位的二进制,范围是0~65535

image-20251031194217385

image-20251031194444114

协议

网络上通信的协议,事先规定的连接规则,以及传输数据的规则被称为网络协议。

开放式网络互联标准:OSI网络参考模型

image-20251031195331412

UDP用户数据报协议

特点:无连接、不可靠通信

image-20251031200112584

TCP传输控制协议

特点:面向连接、可靠通信

最终目标:要保证在不可靠的信道上实现可靠的传输

TCP的三步骤:三次握手建立连接、传输数据进行确认、四次挥手断开连接。

image-20251031201231053

三次握手

image-20251031200605950

四次挥手断开连接

image-20251031201144270

UDP通Data信

java.net.DatagremSocket类

image-20251031201711808

image-20251031202043614

package Basic.src.com.IPDemo.UDPDemo.Demo01;

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

public class Client {
    public static void main(String[] args) throws IOException {
        //1.创建客户端对象(发韭菜出去的人)
        DatagramSocket socket = new DatagramSocket(7777);

        //2.创建数据包对象封装要发出去的数据(创建一个韭菜盒子)
        /*
        * public DatagramPacket(byte buf[], int length,
                          InetAddress address, int port)
                          * 参数一:封装要发出去的数据
                          * 参数二:发生出去的数据大小(字节个数)
                          * 参数三:服务端的IP地址(找到服务端主机)InetAddress.getByName(****)
                          * 参数四:服务器程序的端口
                          * */
        //"我是快乐的客户端,我爱你abc"
        byte[] bytes = "我是快乐的客户端,我爱你abc".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(),6666);

        //开始正式发送这个数据包的数据出去了
        socket.send(packet);

        System.out.println("客户端数据发生完毕");
        socket.close();//释放资源
    }
}
package Basic.src.com.IPDemo.UDPDemo.Demo01;

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

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("-----------------------服务端启动-------------------------");
        //1.创建一个服务端对象(创建一个接韭菜的人)注册端口
        DatagramSocket socket = new DatagramSocket(6666);

        //2.创建一个数据包对象,用于接收数据(创建一个韭菜盘子)
        byte[] buffer = new byte[1024*64];//64KB,一包数据不会超过64Kb
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        //正式使用数据包来接收客户端发来的数据
        socket.receive(packet);

        //4.从字符数组中,把接收到的数据直接打印出来
        //获取本次数据包接收了多少数据
        String rs = new String(buffer, 0, packet.getLength());
        System.out.println(rs);

        System.out.println(packet.getAddress());
        System.out.println(packet.getPort());//客户端(发送端)的端口,系统默认可以随机分配

        socket.close();//释放资源
    }
}

实现多次反复传输

package Basic.src.com.IPDemo.UDPDemo.Demo02;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Cilent {
    public static void main(String[] args) throws Exception {
        //1.创建客户端对象(发韭菜出去的人)
        DatagramSocket socket = new DatagramSocket();//多开端口时不能设定好

        //2.创建数据包对象封装要发出去的数据(创建一个韭菜盒子)
        /*
        * public DatagramPacket(byte buf[], int length,
                          InetAddress address, int port)
                          * 参数一:封装要发出去的数据
                          * 参数二:发生出去的数据大小(字节个数)
                          * 参数三:服务端的IP地址(找到服务端主机)InetAddress.getByName(****)
                          * 参数四:服务器程序的端口
                          * */
        Scanner sc = new Scanner(System.in);
        while (true) {
            //"我是快乐的客户端,我爱你abc"
            System.out.println("请说:");
            String msg = sc.nextLine();
            //在这段代码中,while (true) 循环里的 String msg = sc.nextLine(); 是一个阻塞式操作—— 当程序执行到这行时,会暂停当前线程的执行,
            // 直到用户在控制台输入内容并按下回车,nextLine() 方法才会返回输入的字符串,线程才会继续执行后续的发送逻辑。

            //一旦发现用户输入exit就退出
            if("exit".equals(msg)) {
                System.out.println("欢迎下次光临,退出成功");
                socket.close();//释放资源
                break;//跳出死循环
            }
            byte[] bytes = msg.getBytes();
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(),6666);

            //开始正式发送这个数据包的数据出去了
            socket.send(packet);
        }
    }
}
package Basic.src.com.IPDemo.UDPDemo.Demo02;

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

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("-----------------------服务端启动-------------------------");
        //1.创建一个服务端对象(创建一个接韭菜的人)注册端口
        DatagramSocket socket = new DatagramSocket(6666);

        //2.创建一个数据包对象,用于接收数据(创建一个韭菜盘子)
        byte[] buffer = new byte[1024*64];//64KB,一包数据不会超过64Kb
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            //正式使用数据包来接收客户端发来的数据
            socket.receive(packet);

            //4.从字符数组中,把接收到的数据直接打印出来
            //获取本次数据包接收了多少数据
            String rs = new String(buffer, 0, packet.getLength());
            System.out.println(rs);

            System.out.println(packet.getAddress());
            System.out.println(packet.getPort());//客户端(发送端)的端口,系统默认可以随机分配

            //socket.close();//释放资源,服务端一般不关的
            System.out.println("----------------------------------------------------");
        }
    }
}
posted @ 2025-10-31 22:00  David大胃  阅读(4)  评论(0)    收藏  举报