URL格式:
域名的解析:从右向左解析
域名的层级:
网络编程的本质是进程间通信。
通信的基础是IO模型。
Socket也是一种数据源!
Socket是网络通信的端点。
通过Socket发送数据:
通过Socket接收数据:
同步/异步/阻塞/非阻塞:
- 同步/异步: 关注点在接收方怎样处理。若等待接收方处理完成后返回称同步;接收方收到请求后立即返回给发送方,且接收方处理完成后再将结果通知发送方称为异步。
- 阻塞/非阻塞:关注点在发送方怎样处理。若发送请求的一方(发送者)等待请求的结果,之间不做任何事情,称为阻塞;若发送请求的一方(发送者)等待请求的结果过程中可以去完成其他任务,称为非阻塞。
排列组合:
- 同步阻塞
- 同步非阻塞
- 异步阻塞
- 异步非阻塞
Java提供的线程池:
Java提供的创建线程池的方法:
- newSingleThreadExecutor: 单线程的线程池
- newFixedThreadPool: 可指定数量线程的线程池
- newCachedThreadPool:
- newScheduledThreadPool:
服务端栗子:
package top.onefine.demo.socket;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端
*
* @author one fine<br/>
*/
@Slf4j
public class Server {
private static final int DEFAULT_PORT = 8888; // 监听端口
private static final String QUIT = "quit";
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// 绑定监听端口
serverSocket = new ServerSocket(DEFAULT_PORT);
log.info("服务器已开启,正在监听端口: {}.", DEFAULT_PORT);
while (true) {
// 等待客户端连接
Socket socket = serverSocket.accept(); // 阻塞
log.info("客户端: [{}:{}] 成功连接.", socket.getInetAddress(), socket.getPort());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String msg; // 读取客户端发送的消息
// 注意: 当客户端的输入流关闭, 此时reader.readLine()将返回 null
while ((msg = reader.readLine()) != null) {
// 读取输入缓冲区中的一行数据
// 查看客户端是否退出 客户端可能已经退出,不执行此语句
if (msg.equalsIgnoreCase(QUIT)) {
log.info("客户端: [{}:{}] 退出连接.", socket.getInetAddress(), socket.getPort());
break;
}
log.info("客户端: [{}:{}] 发送消息: {}", socket.getInetAddress(), socket.getPort(), msg);
// 服务端给客户端回复消息
writer.write("服务器响应消息: " + msg + "\n");
writer.flush(); // 刷新缓冲区
}
log.info("客户端: [{}:{}] 退出连接.", socket.getInetAddress(), socket.getPort());
}
} catch (IOException e) {
log.error("Exception: {}", e.getMessage());
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
log.info("服务端ServerSocket关闭.");
} catch (IOException e) {
log.error("Exception: {}", e.getMessage());
}
}
}
}
}
客户端栗子:
package top.onefine.demo.socket;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.Socket;
/**
* 客户端
*
* @author one fine<br/>
*/
@Slf4j
public class Client {
private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
private static final int DEFAULT_SERVER_PORT = 8888;
private static final String QUIT = "quit";
public static void main(String[] args) {
Socket socket;
BufferedWriter writer = null;
try {
// 创建socket
socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
// 创建IO流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
// 等待用户从控制台中输入信息
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String input = consoleReader.readLine();
// 将用户输入的信息发送给服务端
writer.write(input + "\n");
writer.flush();
log.info("客户端发送消息: {}", input);
// 查看用户是否需要退出
if (input.equalsIgnoreCase(QUIT)) {
log.info("客户端退出.");
break;
}
// 读取服务器返回的消息
String msg = reader.readLine();
log.info("客户端收到服务端消息: {}", msg);
}
} catch (IOException e) {
log.error("Exception: {}", e.getMessage());
} finally {
try {
if (writer != null) {
writer.close(); // 即关闭 socket.getOutputStream()
log.info("客户端Socket已关闭.");
}
} catch (IOException e) {
log.error("Exception: {}", e.getMessage());
}
}
}
}