Java Socket点对点通信(基于 TCP)
## ![TIM截图20180508131305.jpg](https://image.xsoftlab.net/baike/articleImages/a082167987078b93b7c549104b8ef46d.jpg)
## 介绍
Socket通常称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过Socket向网络发出请求或者应答网络请求。
Socket是在建立网络连接时使用,在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。·
对于一个网络连接来说,socket是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。
Socket服务器端需要在某个端口上开启服务器端类型的类:java.net.ServerSocket,通过accept()方法用于产生“阻塞”,直到接收到一个连接,并且返回一个客户端的Socket对象实例。
“阻塞”是使程序运行暂时“停留”在这个地方,直到一个会话产生,然后程序继续,通常“阻塞”是由循环产生的。
Socket客户端根据服务器端的IP地址和端口号创建一个Socket对象,连接服务器。
服务器端和客户端都持有一个Socket对象,服务器端的Socket从服务器端指向客户端,而客户端的Socket从客户端指向服务器端,就像在服务器端和客户端建立了两条单向的管道。
### Socket服务器端
```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
private int port;
public SocketServer(int port) {
this.port = port;
try {
start();
} catch (Exception e) {
System.out.println("启动服务器端出现错误:" + e.getMessage());
}
}
// 处理信息
public String infoUpperCase(String line) {
return line.toUpperCase();
}
// 启动服务器端
@SuppressWarnings("resource")
public void start() throws IOException {
// 根据端口创建服务器端Socket对象
ServerSocket serverSocket = new ServerSocket(port);
// 显示连接信息
System.out.println("服务器已启动,监听端口号为:" + port);
System.out.println("正在等待客户端连接.........");
// 挂起等待客户的请求
Socket socketAccept = serverSocket.accept();
// 获取读取客户端的数据流
BufferedReader in = new BufferedReader(new InputStreamReader(socketAccept.getInputStream()));
// 获取写往客户端的数据输出流,true:自动刷新
PrintWriter out = new PrintWriter(socketAccept.getOutputStream(), true);
out.println("服务器端连接成功.........");// 向客户发送连接信息
out.println("输入exit断开与服务器的连接");
boolean done = false;
while (!done) {
// 读取客户端每行的内容
String line = in.readLine();
// 没有写则不读取
if (line == null) {
done = true;
} else {
System.out.println("客户端传来的内容:" + line);
// 信息处理
String message = infoUpperCase(line);
// 向客户端发送信息
out.println("从服务器端口发送的内容:" + message);
// 退出判断
if (line.trim().equals("exit"))
done = true;
}
}
socketAccept.close();
}
public static void main(String[] args) {
try {
new SocketServer(9000);
} catch (Exception e) {
System.out.println("测试服务器端监听出错:" + e.getMessage());
}
}
}
```
### Socket客户端
```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
private String host;
private int port;
public Client(String host, int port) {
this.host = host;
this.port = port;
try {
connectSocket();
} catch (IOException e) {
System.out.println("连接服务器出现I/O错误!");
}
}
public void connectSocket() throws IOException {
Socket socketConn;
// 判断IP地址(域名)如果是本机localhost
if (host.equals("localhost") || host.equals("127.0.0.1")) {
// 创建本地连接
socketConn = new Socket(InetAddress.getLocalHost(), port);
} else {
// 创建远程连接
socketConn = new Socket(InetAddress.getByName(host), port);
}
// 获得键盘的输入流
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
// 获得服务器的输出流
PrintWriter out = new PrintWriter(socketConn.getOutputStream(), true);
// 获得接收服务器发送内容的缓冲流
BufferedReader in = new BufferedReader(new InputStreamReader(socketConn.getInputStream()));
System.out.println("服务器信息:" + in.readLine());// 从服务器获得信息
System.out.println("服务器信息:" + in.readLine());
System.out.print("请输入>");// 用户输入
boolean done = false;
while (!done) {
// 获得从键盘输入的每行字符
String line = stdin.readLine();
// 发送到服务端
out.println(line);
// 读到exit则结束循环
if (line.equalsIgnoreCase("exit"))
done = true;
// 从服务器读取字符串
String info = in.readLine();
// 显示从服务器发送来的数据
System.out.println("服务器信息:" + info);
if (!done)
System.out.print("请输入>");
}
// 关闭资源
socketConn.close();
}
public static void main(String[] args) {
try {
// IP地址为本机,端口为9000
new Client("localhost", 9000);
} catch (Exception e) {
System.out.println("测试客户端连接出错:" + e.getMessage());
}
}
}
```