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服务端正在等待客户端连接...
浏览器