文章目录
- 1. Socket简介
- 2. ServerSocket
- 3. Socket
- 4. 服务器端代码
- 5. 客户端代码
1. Socket简介
Socket(Java套接字)是Java编程语言提供的一组类和接口,用于实现网络通信。它基于Socket编程接口,提供了一种简单而强大的方式来实现网络应用程序。
Socket类库提供了丰富的方法和功能,用于处理网络通信的各个方面。它支持TCP和UDP协议,可以实现可靠的、面向连接的通信(TCP)或不可靠的、无连接的通信(UDP)。Java Socket还提供了一些高级功能,如多线程处理、异步通信、加密通信等,以满足不同网络应用的需求。
本文主要使用Socket实现UDP版的客户端和服务器
-
DatagramSocket
是UDP Socket,用于发送和接收UDP数据报。 -
DatagramPacket
是UDP Socket发送和接收的数据报。
2. ServerSocket
ServerSocket 是创建TCP服务端Socket的API。
方法 | 说明 |
---|---|
ServerSocket(int port) | 创建一个服务端流套接字Socket,并绑定到指定端口 |
ServerSocket 方法:
方法 | 说明 |
---|---|
Socket accept() | 开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket 对象,并基于该Socket建立与客户端的连接,否则阻塞等待 |
void close() | 关闭此套接字 |
3. Socket
Socket API Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端 Socket。
不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据 的。
Socket 构造方法:
方法 | 说明 |
---|---|
Socket(String host, int port) | 创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的 进程建立连接 |
Socket 方法:
方法 | 说明 |
---|---|
InetAddress getInetAddress() | 返回套接字所连接的地址 |
InputStream getInputStream() | 返回此套接字的输入流 |
OutputStream getOutputStream() | 返回此套接字的输出流 |
4. 服务器端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoServer {
// 用于监听客户端
private ServerSocket listenSocket = null;
public TcpEchoServer(int port) throws IOException {
listenSocket = new ServerSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!");
ExecutorService service = Executors.newCachedThreadPool();
while (true) {
// 接收客户端的连接
Socket clientSocket = listenSocket.accept();
service.submit(new Runnable() {
@Override
public void run() {
try {
processConnection(clientSocket);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}
public void processConnection(Socket socket) throws IOException {
System.out.printf("[%s: %d], 客户端上线!\n", socket.getInetAddress().toString(), socket.getPort());
// 处理客户端请求
try (InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()) {
while (true) {
// 读取请求并解析
Scanner scanner = new Scanner(inputStream);
if (!scanner.hasNext()) {
System.out.printf("[%s: %d],客户端下线\n", socket.getInetAddress().toString(), socket.getPort());
break;
}
// 读取请求,并返回响应
String request = scanner.next();
String response = process(request);
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(response);
// 刷新缓冲区
printWriter.flush();
System.out.printf("[%s: %d], req: %s resp: %s \n", socket.getInetAddress().toString(), socket.getPort(),
request, response);
}
} finally {
socket.close();
}
}
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
TcpEchoServer server = new TcpEchoServer(5678);
server.start();
}
}
5. 客户端代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TcpEchoClient {
private Socket socket = null;
public TcpEchoClient(String serverIp, int serverPort) throws IOException {
socket = new Socket(serverIp, serverPort);
}
public void start() throws IOException {
System.out.println("客户端启动!");
Scanner scanner = new Scanner(System.in);
try (InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()) {
while (true) {
// 读取请求
System.out.print("-> ");
String request = scanner.next();
// 发送请求给服务器
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(request);
// 刷新缓冲区
printWriter.flush();
// 读取请求
Scanner respScanner = new Scanner(inputStream);
String response = respScanner.next();
System.out.println(response);
}
}
}
public static void main(String[] args) throws IOException {
TcpEchoClient client = new TcpEchoClient("127.0.0.1", 5678);
client.start();
}
}
运行结果: