Skip to content

Commit 0aaadf3

Browse files
authored
Create SpringBoot整合Socket.md
1 parent adf5407 commit 0aaadf3

File tree

1 file changed

+316
-0
lines changed

1 file changed

+316
-0
lines changed

doc/SpringBoot整合Socket.md

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
```
2+
1.引入web依赖: (用于提供日志依赖的支持)
3+
<dependency>
4+
<groupId>org.springframework.boot</groupId>
5+
<artifactId>spring-boot-starter-web</artifactId>
6+
</dependency>
7+
2.Socket服务端:
8+
[1]手动启动版: (需手动启动;占用主线程;)
9+
public class Server {
10+
private static Logger logger = LoggerFactory.getLogger(Server.class);
11+
// 监听的端口号
12+
private static final int PORT = 8081;
13+
public static void main(String[] args) {
14+
Server server = new Server();
15+
server.init();
16+
}
17+
private void init() {
18+
try {
19+
// new ServerSocket(port[,len]): len为连接请求的队列长度,超过则拒绝
20+
ServerSocket serverSocket = new ServerSocket(PORT);
21+
logger.info("Server Start... ");
22+
while (true) {
23+
//阻塞等待,若请求队列中有连接,则取出一个
24+
Socket client = serverSocket.accept();
25+
// 处理取到的连接
26+
hand(client);
27+
}
28+
} catch (Exception e) {
29+
logger.error("服务器异常: " + e.getMessage());
30+
}
31+
}
32+
private void hand(Socket socket) {
33+
try {
34+
// 读取客户端数据
35+
BufferedReader input =
36+
new BufferedReader(new InputStreamReader(socket.getInputStream()));
37+
// 这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
38+
String clientInputStr = input.readLine();
39+
// 处理客户端数据
40+
logger.info("客户端发过来的内容:" + clientInputStr);
41+
// 向客户端回复信息
42+
PrintStream out = new PrintStream(socket.getOutputStream());
43+
logger.info("请输入:");
44+
// 发送键盘输入的一行
45+
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
46+
out.println(s);
47+
// 关闭流
48+
out.close();
49+
input.close();
50+
} catch (Exception e) {
51+
logger.error("服务器 run 异常: " + e.getMessage());
52+
} finally {
53+
if (socket != null) {
54+
try {
55+
socket.close();
56+
} catch (Exception e) {
57+
logger.error("服务端 finally 异常:" + e.getMessage());
58+
}
59+
}
60+
}
61+
}
62+
}
63+
[2]单线程自动启动版: (随项目启动而启动;不占用主线程,另起一个线程来运行服务)
64+
@Component
65+
public class Server1 {
66+
private static Logger logger = LoggerFactory.getLogger(Server1.class);
67+
//监听的端口号
68+
private static final int PORT = 8081;
69+
// @Component+@PostConstruct实现服务端随项目启动而启动
70+
@PostConstruct
71+
private void start() {
72+
SocketThread socketThread = new SocketThread();
73+
socketThread.start();
74+
}
75+
public static class SocketThread extends Thread {
76+
private ServerSocket serverSocket;
77+
public SocketThread() {
78+
try {
79+
this.serverSocket = new ServerSocket(PORT);
80+
logger.info("Server1 Start...");
81+
} catch (IOException e) {
82+
logger.error("服务器异常: " + e.getMessage());
83+
}
84+
85+
}
86+
@Override
87+
public void run() {
88+
while (!this.isInterrupted()) {
89+
//线程未中断则执行循环
90+
try {
91+
Socket client = serverSocket.accept();
92+
hand(client);
93+
} catch (IOException e) {
94+
logger.error("服务器异常: " + e.getMessage());
95+
}
96+
}
97+
}
98+
private void hand(Socket socket) {
99+
try {
100+
// 读取客户端数据
101+
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
102+
//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
103+
String clientInputStr = input.readLine();
104+
// 处理客户端数据
105+
logger.info("客户端发过来的内容:" + clientInputStr);
106+
// 向客户端回复信息
107+
PrintStream out = new PrintStream(socket.getOutputStream());
108+
logger.info("请输入:");
109+
// 发送键盘输入的一行
110+
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
111+
out.println(s);
112+
//关闭流
113+
out.close();
114+
input.close();
115+
} catch (Exception e) {
116+
logger.info("服务器 run 异常: " + e.getMessage());
117+
} finally {
118+
if (socket != null) {
119+
try {
120+
socket.close();
121+
} catch (Exception e) {
122+
logger.info("服务端 finally 异常:" + e.getMessage());
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
[3]自动启动多线程处理版: (随项目启动而启动;不占用主线程,另起单个线程来运行服务,多线程处理)
130+
@Component
131+
public class Server2 {
132+
private static Logger logger = LoggerFactory.getLogger(Server2.class);
133+
private static final int PORT = 8081;//监听的端口号
134+
// @Component+@PostConstruct实现服务端随项目启动而启动
135+
@PostConstruct
136+
private void start() {
137+
SocketThread socketThread = new SocketThread();
138+
socketThread.start();
139+
}
140+
public static class SocketThread extends Thread {
141+
private ServerSocket serverSocket;
142+
public SocketThread() {
143+
try {
144+
this.serverSocket = new ServerSocket(PORT);
145+
logger.info("Server2 Start...");
146+
} catch (IOException e) {
147+
logger.error("服务器异常: " + e.getMessage());
148+
}
149+
}
150+
@Override
151+
public void run() {
152+
while (!this.isInterrupted()) {
153+
//线程未中断则执行循环
154+
try {
155+
Socket client = serverSocket.accept();
156+
new HandlerThread(client);
157+
} catch (IOException e) {
158+
logger.error("服务器异常: " + e.getMessage());
159+
}
160+
}
161+
}
162+
}
163+
public static class HandlerThread implements Runnable {
164+
private Socket socket;
165+
HandlerThread(Socket client) {
166+
socket = client;
167+
new Thread(this).start();
168+
}
169+
@Override
170+
public void run() {
171+
try {
172+
// 读取客户端数据
173+
BufferedReader input =
174+
new BufferedReader(new InputStreamReader(socket.getInputStream()));
175+
//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
176+
String clientInputStr = input.readLine();
177+
// 处理客户端数据
178+
logger.info("客户端发过来的内容:" + clientInputStr);
179+
// 向客户端回复信息
180+
PrintStream out = new PrintStream(socket.getOutputStream());
181+
logger.info("请输入:");
182+
// 发送键盘输入的一行
183+
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
184+
out.println(s);
185+
//关闭流
186+
out.close();
187+
input.close();
188+
} catch (Exception e) {
189+
logger.info("服务器 run 异常: " + e.getMessage());
190+
} finally {
191+
if (socket != null) {
192+
try {
193+
socket.close();
194+
} catch (Exception e) {
195+
logger.info("服务端 finally 异常:" + e.getMessage());
196+
}
197+
}
198+
}
199+
}
200+
}
201+
}
202+
[4]自动启动多线程处理优化版: (解决上一版本无限创建线程的问题)
203+
@Component
204+
public class Server3 {
205+
private static Logger logger = LoggerFactory.getLogger(Server3.class);
206+
//监听的端口号
207+
private static final int PORT = 8081;
208+
// @Component+@PostConstruct实现服务端随项目启动而启动
209+
@PostConstruct
210+
private void start() {
211+
SocketThread socketThread = new SocketThread();
212+
socketThread.start();
213+
}
214+
public static class SocketThread extends Thread {
215+
private ServerSocket serverSocket;
216+
public SocketThread() {
217+
try {
218+
this.serverSocket = new ServerSocket(PORT);
219+
logger.info("Server Start...");
220+
} catch (IOException e) {
221+
logger.error("服务器异常: " + e.getMessage());
222+
}
223+
}
224+
@Override
225+
public void run() {
226+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
227+
while (!this.isInterrupted()) {
228+
//线程未中断则执行循环
229+
try {
230+
Socket socket = serverSocket.accept();
231+
fixedThreadPool.execute(new Runnable() {
232+
@Override
233+
public void run() {
234+
try {
235+
// 读取客户端数据
236+
BufferedReader input =
237+
new BufferedReader(new InputStreamReader(socket.getInputStream()));
238+
//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException
239+
String clientInputStr = input.readLine();
240+
// 处理客户端数据
241+
logger.info("客户端发过来的内容:" + clientInputStr);
242+
// 向客户端回复信息
243+
PrintStream out = new PrintStream(socket.getOutputStream());
244+
logger.info("请输入:");
245+
// 发送键盘输入的一行
246+
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
247+
out.println(s);
248+
//关闭流
249+
out.close();
250+
input.close();
251+
} catch (Exception e) {
252+
logger.info("服务器 run 异常: " + e.getMessage());
253+
} finally {
254+
if (socket != null) {
255+
try {
256+
socket.close();
257+
} catch (Exception e) {
258+
logger.info("服务端 finally 异常:" + e.getMessage());
259+
}
260+
}
261+
}
262+
}
263+
});
264+
} catch (IOException e) {
265+
logger.error("服务器异常: " + e.getMessage());
266+
}
267+
}
268+
}
269+
}
270+
}
271+
3.通用客户端:
272+
public class Client {
273+
// 服务端端口
274+
private static final int PORT = 8081;
275+
// 服务端IP
276+
private static final String HOST = "localhost";
277+
private static Logger logger = LoggerFactory.getLogger(Client.class);
278+
public static void main(String[] args) {
279+
logger.info("Client Start...");
280+
while (true) {
281+
Socket socket = null;
282+
try {
283+
//创建一个套接字对象并将其连接到指定主机上的指定端口号
284+
socket = new Socket(HOST, PORT);
285+
//读取服务器端数据
286+
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
287+
//向服务器端发送数据
288+
PrintStream out = new PrintStream(socket.getOutputStream());
289+
logger.info("请输入: ");
290+
String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
291+
out.println(str);
292+
String ret = input.readLine();
293+
logger.info("服务器端返回过来的是: " + ret);
294+
// 如接收到 "OK" 则断开连接
295+
if ("OK".equals(ret)) {
296+
logger.info("客户端正在关闭连接...");
297+
Thread.sleep(500);
298+
break;
299+
}
300+
out.close();
301+
input.close();
302+
} catch (Exception e) {
303+
logger.info("客户端异常:" + e.getMessage());
304+
} finally {
305+
if (socket != null) {
306+
try {
307+
socket.close();
308+
} catch (IOException e) {
309+
logger.info("客户端 finally 异常:" + e.getMessage());
310+
}
311+
}
312+
}
313+
}
314+
}
315+
}
316+
```

0 commit comments

Comments
 (0)