/**
* @author : gxd
* @date : 2022/7/19 14:14
* 目标:IP 地址操作类-InetAddress
*
* InetAddress 的使用
* - 此类表示 Internet 协议(IP) 地址。
*
* InetAddress API 如下:
* - public static InetAddress getLocalHost():返回本主机的地址对象
* - public static InetAddress getByName(String host):得到指定主机的 IP 地址对象,参数是域名或者 IP 地址
* - public String getHostName():获取此 IP 地址的主机名
* - public String getHostAddress():返回 IP 地址字符串
* - public boolean isReachable(int timeout):在指定毫秒内连通该 IP 地址对应的主机,连通返回 true
*/
public class InetAddressTest1 {
public static void main(String[] args) throws Exception {
//1、获取本机地址对象
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println(ip1.getHostName());
System.out.println(ip1.getHostAddress());
//2、获取域名 ip 对象
InetAddress ip2 = InetAddress.getByName("www.baidu.com");
System.out.println(ip2.getHostName());
System.out.println(ip2.getHostAddress());
//3、获取公网 IP 对象
InetAddress ip3 = InetAddress.getByName("110.242.68.4");
System.out.println(ip3.getHostName());
System.out.println(ip3.getHostAddress());
//4、判断是否能通:ping 5s之前测试是否可通
System.out.println(ip3.isReachable(5000));
}
}
注意:我们自己开发的程序选择注册端口,且一个设备汇总不能出现两个程序的端口号一样,否则出错。
需求:客户端实现步骤:
需求:接收端实现步骤
发送端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 发送端: 一发 一收
*/
public class ClientTest1 {
public static void main(String[] args) throws Exception {
System.out.println("=============客户端启动===========");
//1、创建发送端对象:发送端自带默认的端口号
DatagramSocket socket = new DatagramSocket();
//2、创建一个数据包对象封装数据
/**
public DatagramPacket(byte buf[], int length,
InetAddress address, int port)
参数一:封装要发送的数据
参数二:发送数据的大小
参数三:服务端的主机 IP 地址
参数四:服务端的接口
*/
byte[] buffer = "你好,接收端!".getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getLocalHost(),8888);
//3、发送数据出去
socket.send(packet);
//4、释放资源
socket.close();
}
}
接收端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 接收端
*/
public class ServerTest2 {
public static void main(String[] args) throws Exception {
System.out.println("=============服务端启动===========");
//1、创建接收端对象:注册端口
DatagramSocket socket = new DatagramSocket(8888);
//2、创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
//3、等待接收数据
socket.receive(packet);
//4、取出数据即可
//读取多少倒出多少
int len = packet.getLength();
String rs = new String(buffer,0,len);
System.out.println("收到了:" + rs);
//获取发送端的 ip 和端口
String ip = packet.getSocketAddress().toString();
System.out.println("对方地址:" + ip);
int port = packet.getPort();
System.out.println("对方端口:" + port);
//5、释放资源
socket.close();
}
}
需求
分析
客户端实现步骤
接收端实现步骤
客户端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 发送端: 多发 多收
*/
public class ClientTest1 {
public static void main(String[] args) throws Exception {
System.out.println("=============客户端启动===========");
//1、创建发送端对象:发送端自带默认的端口号
DatagramSocket socket = new DatagramSocket();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请说:");
String msg = sc.nextLine();
if ("exit".equals(msg)){
System.out.println("连线成功!");
//4、释放资源
socket.close();
break;
}
//2、创建一个数据包对象封装数据
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getLocalHost(),8888);
//3、发送数据出去
socket.send(packet);
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 接收端
*/
public class ServerTest2 {
public static void main(String[] args) throws Exception {
System.out.println("=============服务端启动===========");
//1、创建接收端对象:注册端口
DatagramSocket socket = new DatagramSocket(8888);
//2、创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
while (true) {
//3、等待接收数据
socket.receive(packet);
//4、取出数据即可
//读取多少倒出多少
int len = packet.getLength();
String rs = new String(buffer,0,len);
System.out.println("收到了来自:" + packet.getSocketAddress() + ",对方端口是:" + packet.getPort() +"的消息:" + rs);
}
}
}
客户端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 发送端: 多发 多收
*
* UDP 如何实现广播
* - 使用广播地址:255.255.255.255
* - 具体操作:
* 1. 发送端发送的数据包的目的地写的是广播地址、且指定端口。(255.255.255.255,9999)
* 2. 本机所在网段的其他主机的程序只要匹配端口成功即就可以收到消息了。(9999)
*/
public class ClientTest1 {
public static void main(String[] args) throws Exception {
System.out.println("=============客户端启动===========");
//1、创建发送端对象:发送端自带默认的端口号
DatagramSocket socket = new DatagramSocket();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请说:");
String msg = sc.nextLine();
if ("exit".equals(msg)){
System.out.println("离线成功!");
//4、释放资源
socket.close();
break;
}
//2、创建一个数据包对象封装数据
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getByName("255.255.255.255"),9999);
//3、发送数据出去
socket.send(packet);
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 接收端
*/
public class ServerTest2 {
public static void main(String[] args) throws Exception {
System.out.println("=============服务端启动===========");
//1、创建接收端对象:注册端口
DatagramSocket socket = new DatagramSocket(9999);
//2、创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
while (true) {
//3、等待接收数据
socket.receive(packet);
//4、取出数据即可
//读取多少倒出多少
int len = packet.getLength();
String rs = new String(buffer,0,len);
System.out.println("收到了来自:" + packet.getSocketAddress() + ",对方端口是:" + packet.getPort() +"的消息:" + rs);
}
}
}
客户端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 发送端: 多发 多收
*
* UDP 如何实现组播
* - 使用组播地址:224.0.0.0~239.255.255.255
* - 具体操作:
* 1. 发送端的数据包的目的地是组播 IP(例如:224.0.1.1,端口:9999)
* 1. 接收端必须绑定该组播IP(224.0.1.1),端口还要对应发送端的目的端口9999,这样即可接收该组播消息。
* 1. DatagramSocket的子类 MulticastSocket 可以在接收端绑定组播 IP。
*/
public class ClientTest1 {
public static void main(String[] args) throws Exception {
System.out.println("=============客户端启动===========");
//1、创建发送端对象:发送端自带默认的端口号
DatagramSocket socket = new DatagramSocket();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请说:");
String msg = sc.nextLine();
if ("exit".equals(msg)){
System.out.println("连线成功!");
//4、释放资源
socket.close();
break;
}
//2、创建一个数据包对象封装数据
byte[] buffer = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getByName("224.0.1.1"),9999);
//3、发送数据出去
socket.send(packet);
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/19 17:07
* 接收端
*/
public class ServerTest2 {
public static void main(String[] args) throws Exception {
System.out.println("=============服务端启动===========");
//1、创建接收端对象:注册端口
MulticastSocket socket = new MulticastSocket(9999);
//把当前接收端加入到一个组播组中去:绑定对应的组播消息的组播 IP
//socket.joinGroup(InetAddress.getByName("224.0.1.1"));//过时
socket.joinGroup(new InetSocketAddress(InetAddress.getByName("224.0.1.1"),9999),
NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));
//2、创建一个数据包对象接收数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
while (true) {
//3、等待接收数据
socket.receive(packet);
//4、取出数据即可
//读取多少倒出多少
int len = packet.getLength();
String rs = new String(buffer,0,len);
System.out.println("收到了来自:" + packet.getSocketAddress() + ",对方端口是:" + packet.getPort() +"的消息:" + rs);
}
}
}
注意:在 java 中只要是使用 java.net.Socket 类实现通信,底层即是使用了 TCP 协议
需求:客户端实现步骤
/**
* @author : gxd
* @date : 2022/7/20 23:06
* 目标:完成 Socket网络编程(TCP通信)入门案例的客户端开发,实现1发1收
*
* 客户端实现步骤
* 1. 创建客户端的 Socket 对象,请求与服务端的连接。
* 2. 使用 socket 对象调用 getOutputStream() 方法得到字节输出流。
* 3. 使用字节输出流完成数据的发送。
* 4. 释放资源:关闭 socket 管道。
*/
public class ClientTest1 {
public static void main(String[] args) {
try {
System.out.println("=========客户端启动========");
//1、创建 Socket 通信管道请求有服务端的连接
/**
* public Socket(String host, int port)
* 参数一:服务端的 IP 地址
* 参数二:服务端的端口
*/
Socket socket = new Socket("127.0.0.1",7777);
//2、从 socket 通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3、把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
//4、发送消息
ps.println("我是TCP的客户端,我向你发出邀请:约吗?");
ps.flush();
//关闭资源
//socket.close();//不建议关闭,因为可能发送一半数据就关闭了,出现问题。
} catch (Exception e) {
e.printStackTrace();
}
}
}
需求:服务端实现步骤
服务端:
/**
* @author : gxd
* @date : 2022/7/20 23:23
* 目标:开发 Socket网络编程(TCP通信)入门代码的服务端,实现接收信息
*
* 服务端实现步骤
* 1. 创建 ServerSocket 对象,注册服务端端口。
* 2. 调用 ServerSocket 对象的 accept() 方法,等待客户端的连接,并得到 Socket 管道对象。
* 3. 通过 Socket 对象调用 getInputStream() 方法得到字节输入流、完成数据的接收。
* 4. 释放资源:关闭 Socket 管道
*/
public class ServerTest2 {
public static void main(String[] args) {
try {
System.out.println("=========服务端启动========");
//1、注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//2、必须调用 accept 方法,等待接收客户端的 socket 连接请求,建立 Socket 通信管道
Socket socket = serverSocket.accept();
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接受
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
if ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:" + msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
具体要求:
客户端:
/**
* @author : gxd
* @date : 2022/7/21 9:32
* 目标:使用 TCP 通信方式实现:多发多收消息
*
* 具体要求:
* 1. 可以使用死循环控制服务端收完消息继续等待接收下一个消息。
* 2. 客户端也可以使用死循环等待用户不断输入消息。
* 3. 客户端一旦输入了 exit,则关闭客户端程序,并释放资源。
*/
public class ClientTest1 {
public static void main(String[] args) {
try {
System.out.println("=========客户端启动========");
//1、创建 Socket 通信管道请求有服务端的连接
/**
* public Socket(String host, int port)
* 参数一:服务端的 IP 地址
* 参数二:服务端的端口
*/
Socket socket = new Socket("127.0.0.1",7777);
//2、从 socket 通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3、把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请说:");
String rs = sc.nextLine();
if ("exit".equals(rs)){
//5、释放资源
System.out.println("离线成功!");
socket.close();
break;
}
//4、发送消息
ps.println(rs);
ps.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/21 9:33
* 接收端
*/
public class ServerTest2 {
public static void main(String[] args) {
try {
System.out.println("=========服务端启动========");
//1、注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//2、必须调用 accept 方法,等待接收客户端的 socket 连接请求,建立 Socket 通信管道
Socket socket = serverSocket.accept();
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接受
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:" + msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
本案例实现了多发多收,那么是否可以同时接收多个客户端的消息?
客户端:
/**
* @author : gxd
* @date : 2022/7/21 11:23
* 客户端
*
* 目标:TCP通信-同时接收多个客户端消息
* -引入多线程
*/
public class ClientTest1 {
public static void main(String[] args) {
try {
System.out.println("=========客户端启动========");
//1、创建 Socket 通信管道请求有服务端的连接
/**
* public Socket(String host, int port)
* 参数一:服务端的 IP 地址
* 参数二:服务端的端口
*/
Socket socket = new Socket("127.0.0.1",7777);
//2、从 socket 通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3、把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请说:");
String rs = sc.nextLine();
if ("exit".equals(rs)){
//5、释放资源
System.out.println("离线成功!");
socket.close();
break;
}
//4、发送消息
ps.println(rs);
ps.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/21 11:23
* 服务端
*/
public class ServerTest2 {
public static void main(String[] args) {
try {
System.out.println("=========服务端启动========");
//1、注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//a、定义一个死循环由主线程负责不断的接收客户端的 Socket 管道连接。
while (true){
//2、每接收到一个客户端的 Socket 管道,交给一个独立的子线程负责读取消息
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了!");
//3、开始创建独立线程处理 socket
new ServerReaderThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端线程类
/**
* @author : gxd
* @date : 2022/7/21 11:26
* 服务端读取线程类
*/
public class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接受
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:" + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了!");
}
}
}
客户端:
/**
* @author : gxd
* @date : 2022/7/21 22:47
* 目标:使用线程池优化:实现通信。
* 客户端
*/
public class ClientTest1 {
public static void main(String[] args) {
try {
System.out.println("=========客户端启动========");
//1、创建 Socket 通信管道请求有服务端的连接
/**
* public Socket(String host, int port)
* 参数一:服务端的 IP 地址
* 参数二:服务端的端口
*/
Socket socket = new Socket("127.0.0.1",7777);
//2、从 socket 通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3、把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请说:");
String rs = sc.nextLine();
if ("exit".equals(rs)){
//5、释放资源
System.out.println("离线成功!");
socket.close();
break;
}
//4、发送消息
ps.println(rs);
ps.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端
/**
* @author : gxd
* @date : 2022/7/21 22:47
* 服务端
*/
public class ServerTest2 {
//使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(3,5,
6, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
try {
System.out.println("=========服务端启动========");
//1、注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//a、定义一个死循环由主线程负责不断的接收客户端的 Socket 管道连接。
while (true){
//2、每接收到一个客户端的 Socket 管道,交给一个独立的子线程负责读取消息
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了!");
//任务对象读取消息
Runnable target = new ServerReaderRunnable(socket);
pool.execute(target);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务端Runnable线程
/**
* @author : gxd
* @date : 2022/7/21 22:53
* 服务端Runnable线程
*/
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接受
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:" + msg);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了!");
}
}
}
客户端:
/**
* @author : gxd
* @date : 2022/7/21 23:20
* 目标;TCP通信实战案例-即时通信
* 客户端
*/
public class ClientTest1 {
public static void main(String[] args) {
try {
System.out.println("=========客户端启动========");
//1、创建 Socket 通信管道请求有服务端的连接
Socket socket = new Socket("127.0.0.1",7777);
//创建一个独立的线程专门负责这个客户端的读消息(服务端随时可能转发消息过来!)
new ClientReaderThread(socket).start();
//2、从 socket 通信管道中得到一个字节输出流 负责发送数据
OutputStream os = socket.getOutputStream();
//3、把低级的字节流包装成打印流
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请说:");
String rs = sc.nextLine();
if ("exit".equals(rs)){
//5、释放资源
System.out.println("离线成功!");
socket.close();
break;
}
//4、发送消息
ps.println(rs);
ps.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ClientReaderThread extends Thread{
private Socket socket;
public ClientReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println("收到消息:" + msg);
}
} catch (Exception e) {
System.out.println("服务端把你踢出去了!");
}
}
}
服务端:
/**
* @author : gxd
* @date : 2022/7/21 23:20
* 服务端
*/
public class ServerTest2 {
//定义我一个静态的List集合存储当前全部在线的socket管道
public static List<Socket> allOnlineSockets = new ArrayList<>();
public static void main(String[] args) {
try {
System.out.println("=========服务端启动========");
//1、注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//a、定义一个死循环由主线程负责不断的接收客户端的 Socket 管道连接。
while (true){
//2、每接收到一个客户端的 Socket 管道,交给一个独立的子线程负责读取消息
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress() + "上线了!");
allOnlineSockets.add(socket);//上线完成
//3、开始创建独立线程处理 socket
new ServerReaderThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//3、从 socket 通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//4、把字节输入流包装成缓冲字符输入流进行消息的接收
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//5、按照行读取消息
String msg;
while ((msg = br.readLine()) != null){
System.out.println(socket.getRemoteSocketAddress() + "说了:" + msg);
//把这个消息进行端口转发给全部客户端socket管道
sendMsgToAll(msg,socket);
}
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了!");
ServerTest2.allOnlineSockets.remove(socket);
}
}
/**
* 把消息发送给全部客户端
*/
private void sendMsgToAll(String msg,Socket socket) throws Exception {
for (Socket socket1 : ServerTest2.allOnlineSockets) {
if (socket != socket1){
PrintStream ps = new PrintStream(socket1.getOutputStream());
ps.println(msg);
ps.flush();
}
}
}
}
注意:服务器必须给浏览器响应 HTTP 协议格式的数据,否则浏览器不识别。
HTTP 响应数据的协议格式:就是给浏览器显示的网页信息>
/**
* @author : gxd
* @date : 2022/7/22 15:51
* 目标:TCP通信实战案例-实现BS请求
* 服务端
*/
public class BSserverTest1 {
public static void main(String[] args) {
try {
//1、注册端口
ServerSocket serverSocket = new ServerSocket(8080);
//2、创建一个循环接收多个客户端的请求
while (true) {
Socket socket = serverSocket.accept();
//3、交给一个独立的线程来处理
new ServerReaderThread(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//浏览器 已经与本线程建立了 Socket 管道
//响应消息给浏览器显示
PrintStream ps = new PrintStream(socket.getOutputStream());
//必须响应 HTTP 协议格式数据,否则浏览器不认识消息
ps.println("HTTP/1.1 200 OK");//协议类型和版本 响应成功的消息!
ps.println("Content-Type:text/html;charset=UTF-8");//响应的数据类型:文本/网页
ps.println();//必须发送一个空行
//才可以响应数据回去给浏览器
ps.println("小于不干开发之后去开《炸于店》!!!
");
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @author : gxd
* @date : 2022/7/22 15:51
* 目标:TCP通信实战案例-实现BS请求
* 服务端
*/
public class BSserverTest1 {
//使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
try {
//1、注册端口
ServerSocket serverSocket = new ServerSocket(8080);
//2、创建一个循环接收多个客户端的请求
while (true) {
Socket socket = serverSocket.accept();
//3、交给一个独立的线程来处理
pool.execute(new ServerReaderRunnable(socket));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @author : gxd
* @date : 2022/7/22 16:20
* 服务端Runnable线程
*/
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//浏览器 已经与本线程建立了 Socket 管道
//响应消息给浏览器显示
PrintStream ps = new PrintStream(socket.getOutputStream());
//必须响应 HTTP 协议格式数据,否则浏览器不认识消息
ps.println("HTTP/1.1 200 OK");//协议类型和版本 响应成功的消息!
ps.println("Content-Type:text/html;charset=UTF-8");//响应的数据类型:文本/网页
ps.println();//必须发送一个空行
//才可以响应数据回去给浏览器
ps.println("小于不干开发之后去开《炸于店》!!!
");
ps.close();
} catch (Exception e) {
System.out.println(socket.getRemoteSocketAddress() + "下线了!");
}
}
}