Java中的Socket编程是基于TCP/IP协议的网络通信方式,它允许在网络中的两个或多个应用程序之间建立连接,进行数据的发送和接收。Java通过java.net
和java.nio
(非阻塞IO)包中的类来支持Socket编程。这里主要介绍基于java.net
包的阻塞式Socket编程。
1. 服务器端Socket编程
服务器端首先需要创建一个ServerSocket
对象,该对象负责监听来自客户端的连接请求。一旦接收到连接请求,ServerSocket
就会创建一个新的Socket
对象来表示这个连接,然后服务器就可以通过这个Socket
对象与客户端进行通信。
基本步骤:
- 创建
ServerSocket
对象:指定端口号,也可以指定IP地址来绑定到特定的网络接口。 - 等待连接:通过
ServerSocket
的accept()
方法等待客户端的连接请求。此方法会阻塞,直到接收到连接请求。 - 接收数据:连接建立后,通过
Socket
的getInputStream()
方法获取输入流,然后读取客户端发送的数据。 - 发送数据:通过
Socket
的getOutputStream()
方法获取输出流,然后向客户端发送数据。 - 关闭连接:通信结束后,关闭
Socket
和ServerSocket
资源。
示例代码:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException {
int port = 12345;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
Socket socket = serverSocket.accept(); // 等待客户端连接
System.out.println("New connection accepted");
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Server received: " + inputLine);
out.println("Echo: " + inputLine);
}
}
}
}
}
2. 客户端Socket编程
客户端通过创建一个Socket
对象来连接到服务器。创建Socket
对象时,需要指定服务器的IP地址和端口号。连接建立后,客户端就可以通过Socket
对象的输入流和输出流与服务器进行通信。
基本步骤:
- 创建
Socket
对象:指定服务器的IP地址和端口号。 - 发送数据:通过
Socket
的getOutputStream()
方法获取输出流,然后向服务器发送数据。 - 接收数据:通过
Socket
的getInputStream()
方法获取输入流,然后读取服务器发送的数据。 - 关闭连接:通信结束后,关闭
Socket
资源。
示例代码:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
String hostname = "localhost";
int port = 12345;
try (Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
System.out.println("Enter messages (type QUIT to end):");
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
if (userInput.equalsIgnoreCase("QUIT")) {
break;
}
System.out.println("Server responded: " + in.readLine());
}
}
}
}
注意
- 以上示例代码是简单的阻塞式Socket编程示例,实际应用中可能需要处理多线程、异常处理、网络异常重连等复杂情况。
- Java NIO(非阻塞IO)提供了更高效的IO处理方式,适用于高并发场景。它使用
Selector
来管理多个Channel
(通道),可以实现非阻塞的IO操作。