### 三步学会Java Socket编程
#### 一、Socket编程基础概述
Socket编程是一种非常重要的技术,被广泛应用于网络通信领域。它允许不同计算机上的进程通过网络进行数据交换。在Java中,`Socket`和`ServerSocket`是实现这一功能的关键类。这两个类位于`java.net`包中。
- **Socket**:主要用于客户端程序,它代表了一个网络连接的一端。一旦连接建立,客户端和服务器之间就可以通过读写Socket中的流来进行通信。
- **ServerSocket**:用于服务器端,负责监听特定端口的连接请求。当有客户端请求连接时,`ServerSocket`会创建一个新的`Socket`对象,用于与该客户端进行通信。
#### 二、重要Socket API简介
Java中的Socket编程涉及到多个类和接口,以下是一些重要的API:
1. **java.net.Socket**:提供客户端连接服务的方法。
2. **java.net.ServerSocket**:提供服务器端监听和接受客户端连接的方法。
3. **java.net.SocketAddress**:表示IP地址和端口号的组合。
4. **java.io.InputStream/OutputStream**:用于读取和写入数据。
5. **java.io.Reader/Writer**:用于处理字符数据流。
6. **java.nio.channels.SocketChannel/ServerSocketChannel**:支持非阻塞模式的Socket编程。
#### 三、实现Socket编程的三个步骤
##### 步骤一:创建ServerSocket并监听端口
在服务器端,我们需要创建一个`ServerSocket`实例,并指定监听的端口号。一旦创建完毕,服务器就会开始监听该端口上的连接请求。
```java
ServerSocket serverSocket = new ServerSocket(10000);
```
这里使用端口号10000作为示例,实际应用中可以选择一个合适的端口号。端口号通常应该大于1024,因为小于1024的端口往往被操作系统保留用于特定的服务。
##### 步骤二:接收客户端连接
当客户端尝试连接到服务器时,服务器端将通过调用`accept()`方法来接受新的连接。这将返回一个新的`Socket`对象,服务器可以通过这个对象与客户端通信。
```java
Socket clientSocket = serverSocket.accept();
```
##### 步骤三:通过Socket进行读写操作
一旦连接建立,服务器和客户端都可以通过`Socket`对象进行数据交换。数据交换通常是通过读取和写入`InputStream`和`OutputStream`来完成的。
- **读取数据**:
- 从`Socket`获取输入流。
- 使用`BufferedReader`等工具类进行读取。
```java
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
```
- **写入数据**:
- 从`Socket`获取输出流。
- 使用`PrintWriter`等工具类进行写入。
```java
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
```
#### 四、示例代码分析
下面是一个简单的服务器端和客户端的示例代码。
**服务器端代码**:
```java
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Server {
private ServerSocket ss;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Server() {
try {
ss = new ServerSocket(10000);
while (true) {
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
String line = in.readLine();
out.println("you input is: " + line);
out.close();
in.close();
socket.close();
}
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}
```
**客户端代码**:
```java
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Client {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Client() {
try {
socket = new Socket("xxx.xxx.xxx.xxx", 10000);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader line = new BufferedReader(new InputStreamReader(System.in));
out.println(line.readLine());
line.close();
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client();
}
}
```
这段代码展示了如何创建服务器端和客户端,以及如何通过Socket进行基本的数据交互。需要注意的是,这里的代码仅作为演示,实际应用中还需要考虑异常处理和其他高级特性,如多线程处理等。