uacs2024

导航

Java基础5 网络

网络

InetAddress获取本机IP对象和对方IP对象

InetAddressDemo1.java

import java.net.InetAddress;

public class InetAddressDemo1 {
    public static void main(String[] args) {
        //目标:认识InetAddress获取本机IP对象和对方IP对象
        try {
            //1.获取本机IP对象
            InetAddress local = InetAddress.getLocalHost();
            System.out.println(local);//LAPTOP-********/192.168.84.1
            System.out.println(local.getHostName());//LAPTOP-********
            System.out.println(local.getHostAddress());//192.168.84.1

            //2.获取对方IP对象
            InetAddress remote = InetAddress.getByName("www.baidu.com");
            System.out.println(remote);//www.baidu.com/153.3.238.28
            System.out.println(remote.getHostName());//www.baidu.com
            System.out.println(remote.getHostAddress());//153.3.238.28

            //3.判断本机与对方主机在规定时间内是否连接
            System.out.println(remote.isReachable(5000));//true

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

 

UDP1    单发单收

UDPServerDemo2.java      UDP服务端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;
public class UDPServerDemo2 { public static void main(String[] args) throws Exception{ //目标:完成UDP通信多发多收:服务端开发 System.out.println(new Date() + "------------服务端启动------------"); //1.创建接收端对象,注册端口 DatagramSocket socket = new DatagramSocket(10086); //2.创建数据包对象,封装要接收的数据 byte[] bytes = new byte[1024 * 64]; DatagramPacket packet = new DatagramPacket(bytes,bytes.length); //3.接收数据,将数据封装到数据包对象的字节数组中 socket.receive(packet); int len = packet.getLength();//获取接收到的数据长度 String data = new String(bytes,0,len); System.out.println(new Date() + "接收到的数据为:" + data); //获取对方的IP地址和端口号 String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); System.out.println(new Date() + "对方的IP地址为:" + ip + ",端口号为:" + port); socket.close(); } }

 

UDPClientDemo1.java      UDP客户端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;
public class UDPClientDemo1 { public static void main(String[] args) throws Exception{ //目标:完成UDP通信一发一收:客户端开发 System.out.println(new Date() + "------------客户端启动------------"); //1.创建发送端对象 DatagramSocket socket = new DatagramSocket();//随机端口 //2.创建数据包对象封装要发送的数据 byte[] bytes = "你好,我是客户端。hello,I am client".getBytes(); /** * public DatagramPacket(byte buf[], int length, * InetAddress address, int port) * 参数一:发送的数据,字节数组 * 参数二:发送的字节长度。 * 参数三:目的地的IP地址。 * 参数四:服务端程序的端口号 */ DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),10086); //3.让发送端对象发送数据包的数据 socket.send(packet); socket.close(); } }

先启动服务端,再启动客户端

服务端

Fri Jun 06 21:07:41 CST 2025------------服务端启动------------
Fri Jun 06 21:07:52 CST 2025 接收到的数据为:你好,我是客户端。hello,I am client
Fri Jun 06 21:07:52 CST 2025 对方的IP地址为:10.11.45.76,端口号为:49307

客户端

Fri Jun 06 21:07:52 CST 2025------------客户端启动------------

 

 

UDP2    多发多收

UDPServerDemo2.java  

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;

public class UDPServerDemo2 {
    public static void main(String[] args) throws Exception{
        //目标:完成UDP通信一发一收:服务端开发
        System.out.println(new Date() + "------------服务端启动------------");
        //1.创建接收端对象,注册端口
        DatagramSocket socket = new DatagramSocket(10086);

        //2.创建数据包对象,封装要接收的数据
        byte[] bytes = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(bytes,bytes.length);

        while (true) {
            //3.接收数据,将数据封装到数据包对象的字节数组中
            socket.receive(packet);//等待式接收数据

            int len = packet.getLength();//获取接收到的数据长度
            String data = new String(bytes,0,len);
            System.out.println(new Date() + "接收到的数据为:" + data);

            //获取对方的IP地址和端口号
            String ip = packet.getAddress().getHostAddress();
            int port = packet.getPort();
            System.out.println(new Date() + "对方的IP地址为:" + ip + ",端口号为:" + port);

            System.out.println(new Date() + "------------------------------------------");
        }
    }
}

 

UDPClientDemo1.java

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Date;
import java.util.Scanner;

public class UDPClientDemo1 {
    public static void main(String[] args) throws Exception{
        //目标:完成UDP通信多发多收:客户端开发
        System.out.println(new Date() + "------------客户端启动------------");
        //1.创建发送端对象
        DatagramSocket socket = new DatagramSocket();//随机端口

        Scanner sc = new Scanner(System.in);
        while (true) {
            //2.创建数据包对象封装要发送的数据
            System.out.println(new Date() + "请输入要发送的内容:");
            String msg = sc.nextLine();

            //如果用户输入的是 "exit",则结束发送
            if ("exit".equals(msg)) {
                System.out.println(new Date() + "------------客户端退出了------------");
                socket.close();break;
            }

            byte[] bytes = msg.getBytes();

            DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),10086);

            //3.让发送端对象发送数据包的数据
            socket.send(packet);
        }
    }
}

服务端

Fri Jun 06 21:18:21 CST 2025------------服务端启动------------
Fri Jun 06 21:18:30 CST 2025接收到的数据为:123
Fri Jun 06 21:18:30 CST 2025对方的IP地址为:192.168.84.1,端口号为:55842
Fri Jun 06 21:18:30 CST 2025------------------------------------------
Fri Jun 06 21:18:32 CST 2025接收到的数据为:456
Fri Jun 06 21:18:32 CST 2025对方的IP地址为:192.168.84.1,端口号为:55842
Fri Jun 06 21:18:32 CST 2025------------------------------------------
Fri Jun 06 21:18:35 CST 2025接收到的数据为:789
Fri Jun 06 21:18:35 CST 2025对方的IP地址为:192.168.84.1,端口号为:55842
Fri Jun 06 21:18:35 CST 2025------------------------------------------

客户端

Fri Jun 06 21:18:25 CST 2025------------客户端启动------------
Fri Jun 06 21:18:25 CST 2025请输入要发送的内容:
123
Fri Jun 06 21:18:30 CST 2025请输入要发送的内容:
456
Fri Jun 06 21:18:32 CST 2025请输入要发送的内容:
789
Fri Jun 06 21:18:35 CST 2025请输入要发送的内容:
exit
Fri Jun 06 21:18:41 CST 2025------------客户端退出了------------

 

 

TCP1      单发单收

TCPServerDemo2.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 1.创建ServerSocket对象,注册服务端端口。
 * 2.调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
 * 3.通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 4.释放资源:关闭socket管道
 */

public class TCPServerDemo2 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------服务端启动了----------------------");
        //目标:实现TCP通信:一发一收:服务端开发。
        //1.创建服务端ServerSocket对象,绑定端口号,监听客户端连接
        ServerSocket ss = new ServerSocket(9999);
        //2.调用ServerSocket对象的accept方法,阻塞等待客户端连接,一旦有客户端连接,就返回一个Socket对象
        System.out.println(new Date() + "服务端正在等待客户端连接...");
        Socket socket = ss.accept();
        //3.获取输入流,读取客户端发送的数据
        InputStream is = socket.getInputStream();
        //4.把字节输入流包装成特殊数据输入流
        DataInputStream dis = new DataInputStream(is);
        //5.读取数据
        int num = dis.readInt();
        String msg = dis.readUTF();
        System.out.println(new Date() + "服务端接收到客户端发送的数据:" + "num = " + num + " , msg = \"" + msg + "\"");
        //6.获取客户端地ip和端口号
        System.out.println(new Date() + "客户端的ip:" + socket.getInetAddress().getHostAddress());
        System.out.println(new Date() + "客户端的端口:" + socket.getPort());
    }
}

TCPClientDemo1.java

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Date;

/**
 * 1.创建客户端的Socket对象,请求与服务端的连接,
 * 2.使用socket对象调用getOutputStream()方法得到字节输出流
 * 3.使用字节输出流完成数据的发送
 * 4.释放资源:关闭socket管道
 */

public class TCPClientDemo1 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------客户端启动了----------------------");
        //目标:实现TCP通信:一发一收:客户端开发。
        //1.常见Socket管道对象,请求与服务端的Socket链接。可靠链接.
        Socket socket = new Socket("127.0.0.1",9999);
        //2.从Socket通信管道中得到一个字节输出流
        OutputStream os = socket.getOutputStream();
        //3.把字节输出流包装成特殊流,打印什么就直接显示什么
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeInt(520);
        dos.writeUTF(new Date() + "你好,我是TCP客户端");
        //4.关闭资源
        socket.close();
    }
}

服务端

Fri Jun 06 21:44:08 CST 2025----------------------客户端启动了----------------------

客户端

Fri Jun 06 21:44:02 CST 2025----------------------服务端启动了----------------------
Fri Jun 06 21:44:02 CST 2025服务端正在等待客户端连接...
Fri Jun 06 21:44:08 CST 2025服务端接收到客户端发送的数据:num = 520 , msg = "Fri Jun 06 21:44:08 CST 2025你好,我是TCP客户端"
Fri Jun 06 21:44:08 CST 2025客户端的ip:127.0.0.1
Fri Jun 06 21:44:08 CST 2025客户端的端口:10657

 

 

TCP2      多发多收,客户端断开服务端也跟着断开

TCPServerDemo2.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 1.创建ServerSocket对象,注册服务端端口。
 * 2.调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
 * 3.通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 4.释放资源:关闭socket管道
 */

public class TCPServerDemo2 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------服务端启动----------------------");
        //目标:实现TCP通信:多发多收:服务端开发。
        //1.创建服务端ServerSocket对象,绑定端口号,监听客户端连接
        ServerSocket ss = new ServerSocket(9999);
        //2.调用ServerSocket对象的accept方法,阻塞等待客户端连接,一旦有客户端连接,就返回一个Socket对象。
        System.out.println(new Date() + " 服务端正在等待客户端连接...");

        Socket socket = ss.accept();
        //3.获取输入流,读取客户端发送的数据
        InputStream is = socket.getInputStream();
        //4.把字节输入流包装成特殊数据输入流
        DataInputStream dis = new DataInputStream(is);

        //5.读取数据
        while (true) {
            try {
                String msg = dis.readUTF(); // 等待读取客户端发送的数据
                System.out.println(new Date() + " 服务端接收到客户端发送的数据:" + " msg = " + "\"" + msg + "\"");
                System.out.println("客户端IP: " + socket.getInetAddress().getHostAddress());
                System.out.println("客户端端口: " + socket.getPort());
                System.out.println("--------------------------------------------------");
            } catch (Exception e) {
                System.out.println(new Date() + " 客户端已断开连接!");
                socket.close(); // 关闭服务端Socket
                break; // 退出循环
            }
        }
    }
}

TCPClientDemo1.java

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;

/**
 * 1.创建客户端的Socket对象,请求与服务端的连接,
 * 2.使用socket对象调用getOutputStream()方法得到字节输出流
 * 3.使用字节输出流完成数据的发送
 * 4.释放资源:关闭socket管道
 */

public class TCPClientDemo1 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------客户端启动----------------------");
        //目标:实现TCP通信:多发多收:客户端开发。
        //1.常见Socket管道对象,请求与服务端的Socket链接。可靠链接.
        Socket socket = new Socket("127.0.0.1",9999);
        //2.从Socket通信管道中得到一个字节输出流
        OutputStream os = socket.getOutputStream();
        //3.把字节输出流包装成特殊流,打印什么就直接显示什么
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println(new Date() + " 请输入您要发送给服务端的内容:");
            String msg = sc.nextLine();
            if("exit".equals(msg)){
                System.out.println(new Date() + "----------------------客户端退出----------------------");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(new Date() + " " + msg);
            dos.flush();
        }
    }
}

服务端

Sat Jun 07 16:12:50 CST 2025----------------------服务端启动----------------------
Sat Jun 07 16:12:50 CST 2025 服务端正在等待客户端连接...
Sat Jun 07 16:13:06 CST 2025 服务端接收到客户端发送的数据: msg = "Sat Jun 07 16:13:06 CST 2025 123"
客户端IP: 127.0.0.1
客户端端口: 4582
--------------------------------------------------
Sat Jun 07 16:13:11 CST 2025 服务端接收到客户端发送的数据: msg = "Sat Jun 07 16:13:11 CST 2025 456"
客户端IP: 127.0.0.1
客户端端口: 4582
--------------------------------------------------
Sat Jun 07 16:13:17 CST 2025 服务端接收到客户端发送的数据: msg = "Sat Jun 07 16:13:17 CST 2025 789"
客户端IP: 127.0.0.1
客户端端口: 4582
--------------------------------------------------
Sat Jun 07 16:13:20 CST 2025 客户端已断开连接!

客户端

Sat Jun 07 16:12:54 CST 2025----------------------客户端启动----------------------
Sat Jun 07 16:12:54 CST 2025 请输入您要发送给服务端的内容:
123
Sat Jun 07 16:13:06 CST 2025 请输入您要发送给服务端的内容:
456
Sat Jun 07 16:13:11 CST 2025 请输入您要发送给服务端的内容:
789
Sat Jun 07 16:13:17 CST 2025 请输入您要发送给服务端的内容:
exit
Sat Jun 07 16:13:20 CST 2025----------------------客户端退出----------------------

 

 

TCP2_2      多发多收,一个客户端断开不会影响其他客户端

TCPServerDemo2.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 1.创建ServerSocket对象,注册服务端端口。
 * 2.调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
 * 3.通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 4.释放资源:关闭socket管道
 */

public class TCPServerDemo2 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------服务端启动----------------------");
        //目标:实现TCP通信:多发多收:服务端开发。
        //1.创建服务端ServerSocket对象,绑定端口号,监听客户端连接
        ServerSocket ss = new ServerSocket(9999);

        while (true) { // 外层循环:持续等待新客户端连接
            System.out.println(new Date() + " 服务端正在等待客户端连接...");
            Socket socket = ss.accept(); // 阻塞等待客户端连接

            /**
             * 多线程必要性:避免服务端在处理一个客户端时阻塞其他客户端的连接请求。
             * 资源释放:每个线程负责关闭自己的 Socket,避免资源泄漏。
             * 扩展性:如需限制最大连接数,可用线程池(如 ExecutorService)。
             */
            new Thread(() -> {
                try {
                    //3.获取输入流,读取客户端发送的数据
                    InputStream is = socket.getInputStream();
                    //4.把字节输入流包装成特殊数据输入流
                    DataInputStream dis = new DataInputStream(is);

                    while (true) { // 内层循环:处理当前客户端的消息
                        try {
                            String msg = dis.readUTF();
                            System.out.println(new Date() + " 收到来自 " +
                                    socket.getInetAddress().getHostAddress() + ":" +
                                    socket.getPort() + " 的消息: \"" + msg + "\"");
                        } catch (Exception e) {
                            System.out.println(new Date() + " 客户端 " +
                                    socket.getInetAddress().getHostAddress() + ":" +
                                    socket.getPort() + " 已断开连接");
                            socket.close(); // 关闭当前客户端连接
                            break; // 退出内层循环,线程结束
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

TCPClientDemo1.java

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;

/**
 * 1.创建客户端的Socket对象,请求与服务端的连接,
 * 2.使用socket对象调用getOutputStream()方法得到字节输出流
 * 3.使用字节输出流完成数据的发送
 * 4.释放资源:关闭socket管道
 */

public class TCPClientDemo1 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------客户端启动----------------------");
        //目标:实现TCP通信:多发多收:客户端开发。
        //1.常见Socket管道对象,请求与服务端的Socket链接。可靠链接.
        Socket socket = new Socket("127.0.0.1",9999);
        //2.从Socket通信管道中得到一个字节输出流
        OutputStream os = socket.getOutputStream();
        //3.把字节输出流包装成特殊流,打印什么就直接显示什么
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println(new Date() + " 请输入您要发送给服务端的内容:");
            String msg = sc.nextLine();
            if("exit".equals(msg)){
                System.out.println(new Date() + "----------------------客户端退出----------------------");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(new Date() + " : " + msg);
            dos.flush();
        }
    }
}

服务端

Sat Jun 07 16:30:15 CST 2025----------------------服务端启动----------------------
Sat Jun 07 16:30:15 CST 2025 服务端正在等待客户端连接...
Sat Jun 07 16:30:18 CST 2025 服务端正在等待客户端连接...
Sat Jun 07 16:33:10 CST 2025 服务端正在等待客户端连接...
Sat Jun 07 16:33:20 CST 2025 收到来自 127.0.0.1:1751 的消息: "Sat Jun 07 16:33:20 CST 2025 : 123"
Sat Jun 07 16:33:25 CST 2025 收到来自 127.0.0.1:3490 的消息: "Sat Jun 07 16:33:25 CST 2025 : 456"
Sat Jun 07 16:33:41 CST 2025 收到来自 127.0.0.1:1751 的消息: "Sat Jun 07 16:33:41 CST 2025 : 321"
Sat Jun 07 16:33:46 CST 2025 收到来自 127.0.0.1:3490 的消息: "Sat Jun 07 16:33:46 CST 2025 : 654"
Sat Jun 07 16:33:59 CST 2025 客户端 127.0.0.1:1751 已断开连接
Sat Jun 07 16:34:05 CST 2025 客户端 127.0.0.1:3490 已断开连接

客户端1

Sat Jun 07 16:30:18 CST 2025----------------------客户端启动----------------------
Sat Jun 07 16:30:18 CST 2025 请输入您要发送给服务端的内容:
123
Sat Jun 07 16:33:20 CST 2025 请输入您要发送给服务端的内容:
321
Sat Jun 07 16:33:41 CST 2025 请输入您要发送给服务端的内容:
exit
Sat Jun 07 16:33:59 CST 2025----------------------客户端退出----------------------

客户端2

Sat Jun 07 16:33:10 CST 2025----------------------客户端启动----------------------
Sat Jun 07 16:33:10 CST 2025 请输入您要发送给服务端的内容:
456
Sat Jun 07 16:33:25 CST 2025 请输入您要发送给服务端的内容:
654
Sat Jun 07 16:33:46 CST 2025 请输入您要发送给服务端的内容:
exit
Sat Jun 07 16:34:05 CST 2025----------------------客户端退出----------------------

 

 

TCP3

ServerReader.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.Date;

public class ServerReader extends Thread{
    private Socket socket;
    public ServerReader(Socket socket) { this.socket = socket; }
    @Override
    public void run(){
        try {
            //读取管道信息
            //3.获取输入流,读取客户端发送的数据
            InputStream is = socket.getInputStream();
            //4.把字节输入流包装成特殊数据输入流
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                String msg = dis.readUTF();//等待读取客户端发送的数据
                System.out.println(new Date() + " 服务端接收到客户端发送的数据 " + " msg = " + "\"" + msg + "\"");
                //6.获取客户端地ip和端口号
                System.out.println("客户端的ip:" + socket.getInetAddress().getHostAddress());
                System.out.println("客户端的端口:" + socket.getPort());
                System.out.println("--------------------------------------------------");
            }
        }catch (Exception e){
            System.out.println(new Date() + " 客户端" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "已断开连接");
        }
    }
}

TCPServerDemo2.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 1.创建ServerSocket对象,注册服务端端口。
 * 2.调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
 * 3.通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 4.释放资源:关闭socket管道
 */

public class TCPServerDemo2 {
    public static void main(String[] args) throws Exception{
        System.out.println(new Date() + "----------------------服务端启动----------------------");
        //目标:实现TCP通信:多发多收:服务端开发。
        //1.创建服务端ServerSocket对象,绑定端口号,监听客户端连接
        ServerSocket ss = new ServerSocket(9999);

        while (true) {
            //2.调用ServerSocket对象的accept方法,阻塞等待客户端连接,一旦有客户端连接,就返回一个Socket对象。
            System.out.println(new Date() + "服务端正在等待客户端连接...");
            Socket socket = ss.accept();
            System.out.println(new Date() + "客户端 " + socket.getInetAddress().getHostAddress() + " 已连接");
            new ServerReader(socket).start();
        }
    }
}

TCPClientDemo1.java

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * 1.创建客户端的Socket对象,请求与服务端的连接,
 * 2.使用socket对象调用getOutputStream()方法得到字节输出流
 * 3.使用字节输出流完成数据的发送
 * 4.释放资源:关闭socket管道
 */

public class TCPClientDemo1 {
    public static void main(String[] args) throws Exception{
        System.out.println("----------------------客户端启动----------------------");
        //目标:实现TCP通信:多发多收:客户端开发。
        //1.常见Socket管道对象,请求与服务端的Socket链接。可靠链接.
        Socket socket = new Socket("127.0.0.1",9999);
        //2.从Socket通信管道中得到一个字节输出流
        OutputStream os = socket.getOutputStream();
        //3.把字节输出流包装成特殊流,打印什么就直接显示什么
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入您要发送给服务端的内容:");
            String msg = sc.nextLine();
            if("exit".equals(msg)){
                System.out.println("----------------------客户端退出----------------------");
                dos.close();
                socket.close();
                break;
            }
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

服务端

Sat Jun 07 17:03:59 CST 2025----------------------服务端启动----------------------
Sat Jun 07 17:03:59 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:04:03 CST 2025客户端 127.0.0.1 已连接
Sat Jun 07 17:04:03 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:04:07 CST 2025客户端 127.0.0.1 已连接
Sat Jun 07 17:04:07 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:04:18 CST 2025 服务端接收到客户端发送的数据  msg = "123"
客户端的ip:127.0.0.1
客户端的端口:12379
--------------------------------------------------
Sat Jun 07 17:04:23 CST 2025 服务端接收到客户端发送的数据  msg = "456"
客户端的ip:127.0.0.1
客户端的端口:12385
--------------------------------------------------
Sat Jun 07 17:04:28 CST 2025 服务端接收到客户端发送的数据  msg = "654"
客户端的ip:127.0.0.1
客户端的端口:12385
--------------------------------------------------
Sat Jun 07 17:04:34 CST 2025 服务端接收到客户端发送的数据  msg = "321"
客户端的ip:127.0.0.1
客户端的端口:12379
--------------------------------------------------
Sat Jun 07 17:04:38 CST 2025 客户端127.0.0.1:12379已断开连接
Sat Jun 07 17:04:44 CST 2025 客户端127.0.0.1:12385已断开连接

客户端1

----------------------客户端启动----------------------
请输入您要发送给服务端的内容:
123
请输入您要发送给服务端的内容:
321
请输入您要发送给服务端的内容:
exit
----------------------客户端退出----------------------

客户端2

----------------------客户端启动----------------------
请输入您要发送给服务端的内容:
456
请输入您要发送给服务端的内容:
654
请输入您要发送给服务端的内容:
exit
----------------------客户端退出----------------------

 

 

TCP4_BS

ServerReaderRunnable.java

import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Date;

public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public ServerReaderRunnable(Socket socket) { this.socket = socket; }
    @Override
    public void run(){
        try {
            //1.给当前对应的浏览器管道响应一个网页数据回去。
            OutputStream os = socket.getOutputStream();
            //2.通过字节输出流包装写出去数据给浏览器
            PrintStream ps = new PrintStream(os);
            //3.写相应的网页数据给浏览器
            ps.println("HTTP/1.1 200 OK");
            ps.println("Content-Type:text/html;charset=utf-8");
            ps.println();//这里必须空一行
            ps.println("<html>");
                ps.println("<head>");
                    ps.println("<meta charset='utf-8'>");
                    ps.println("<title>");
                        ps.println("这是浏览器窗口标题");
                    ps.println("</title>");
                ps.println("</head>");
                ps.println("<body>");
                    ps.println("<h1 style='color:red;font-size=20px'>这是一个body</h1>");
                    ps.println("<img src='itheima.com/images/logo.png'>");
                ps.println("</body>");
            ps.println("</html>");
            ps.close();
            socket.close();
        }catch (Exception e){
            System.out.println(new Date() + "客户端" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "已断开连接");
        }
    }
}

TCPServerDemo2.java

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.*;

/**
 * 1.创建ServerSocket对象,注册服务端端口。
 * 2.调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象
 * 3.通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
 * 4.释放资源:关闭socket管道
 */

public class TCPServerDemo2 {
    public static void main(String[] args) throws Exception{
        //目标:BS架构原理理解:服务端
        //服务器必须给浏览器响应HTTP协议规定的数据格式,否则浏览器不识别返回的数据
        System.out.println(new Date() + "----------------------服务端启动----------------------");
        //1.创建服务端ServerSocket对象,绑定端口号,监听客户端连接
        ServerSocket ss = new ServerSocket(9999);

        ExecutorService pool = new ThreadPoolExecutor(3,10,10,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        System.out.println("服务端地址" + InetAddress.getLocalHost().getHostAddress() + ":9999");
        while (true) {
            //2.调用ServerSocket对象的accept方法,阻塞等待客户端连接,一旦有客户端连接,就返回一个Socket对象。
            System.out.println(new Date() + "服务端正在等待客户端连接...");
            Socket socket = ss.accept();
            System.out.println(new Date() + " 客户端" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() +"已连接");
            pool.execute(new ServerReaderRunnable(socket));
        }
    }
}

服务端

Sat Jun 07 17:48:55 CST 2025----------------------服务端启动----------------------
服务端地址192.168.84.1:9999
Sat Jun 07 17:48:55 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:49:04 CST 2025 客户端192.168.84.1:3461已连接
Sat Jun 07 17:49:04 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:49:04 CST 2025 客户端192.168.84.1:3462已连接
Sat Jun 07 17:49:04 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:49:04 CST 2025 客户端192.168.84.1:3464已连接
Sat Jun 07 17:49:04 CST 2025服务端正在等待客户端连接...
Sat Jun 07 17:49:04 CST 2025 客户端192.168.84.1:3465已连接
Sat Jun 07 17:49:04 CST 2025服务端正在等待客户端连接...

浏览器

 

posted on 2025-06-06 21:31  ᶜʸᵃⁿ  阅读(6)  评论(0)    收藏  举报