springBoot启动socket服务端
socket服务端简单实现实例
- springBoot启动socket服务端
-
- SOCKET服务端启动
- SOCKET客户端连接测试
-
- 模拟业务处理线程类
- 模拟监测服务心跳线程类
- 补充一下目录结构分布
- 测试输出效果
SOCKET服务端启动
通过以下两个类实现了springboot启动类,启动socket服务端
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Component
public class ServerSocketConfig {
private static Logger log = LoggerFactory.getLogger(ServerSocketConfig.class);
public static ServerSocket serverSocket = null;
private static final ThreadPoolExecutor threadpool = new ThreadPoolExecutor(15, 15,
10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
@Bean
public void socketCreate() {
try {
serverSocket = new ServerSocket(5030);
log.info("socket服务端开启");
while (true){
Socket socket = serverSocket.accept();
System.out.println("接收到客户端socket" + socket.getRemoteSocketAddress());
threadpool.execute(new ServerReceiveThread(socket));
}
} catch (IOException e) {
log.info("socket服务启动异常");
e.printStackTrace();
}
}
}
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ServerReceiveThread implements Runnable {
private Socket socket;
private static Logger log = LoggerFactory.getLogger(ServerReceiveThread.class);
public ServerReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//输入流接收数据
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
//输出流发送数据
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
while (true) {
JSONObject jsonObject = (JSONObject) ois.readObject();
System.out.println(jsonObject.toJSONString());
String message = jsonObject.getString("msg");
if ("close".equals(message)) {
oos.writeUTF("close");
oos.flush();
break;
} else {
oos.writeUTF("接收数据成功" + message);
oos.flush();
}
}
log.info("服务端关闭客户端[{}]", socket.getRemoteSocketAddress());
oos.close();
ois.close();
socket.close();
} catch (Exception e) {
log.info("接收数据异常socket关闭");
e.printStackTrace();
} finally {
log.info("数据异常数据要怎么保留");
}
}
}
SOCKET客户端连接测试
模拟测试客户端连接-主测试类
package test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ClientTest {
private static final ExecutorService executorService = Executors.newFixedThreadPool(5);
private static String host = "127.0.0.1";
private static int port = 5030;
public static void main(String[] args) {
executorService.execute(new ClientHeartThread(host,port));
executorService.execute(new ClientPrintThread(host,port));
// new Thread(new ClientPrintThread(host,port)).start();
// new Thread(new ClientHeartThread(host,port)).start();
}
}
可以使用线程池或者多个线程类start都可以就是我注释的地方
模拟业务处理线程类
package test;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientPrintThread implements Runnable{
private String host;
private int port;
public ClientPrintThread(String host,int port){
this.host = host;
this.port = port;
}
@Override
public void run() {
try {
Socket socket = new Socket(host,port);
System.out.println("业务socket链接成功");
//输出流写数据
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
//输入流读数据
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true){
String str = scanner.nextLine();
JSONObject jsonObject = new JSONObject();
jsonObject.put("type","body");
jsonObject.put("msg",str);
oos.writeObject(jsonObject);
oos.flush();
//写的部分
String message = ois.readUTF();
System.out.println("接收到服务端响应"+message);
if("close".equals(message)){
break;
}
}
ois.close();
oos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
模拟监测服务心跳线程类
package test;
import com.alibaba.fastjson.JSONObject;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ClientHeartThread implements Runnable{
private String host;
private int port;
public ClientHeartThread(String host, int port){
this.host = host;
this.port = port;
}
@Override
public void run() {
try {
Socket socket = new Socket(host,port);
System.out.println("心跳socket链接成功");
//输出流写数据
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
//输入流读数据
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
int i =0;
while (true){
Thread.sleep(3000);
JSONObject jsonObject = new JSONObject();
jsonObject.put("type","heart");
jsonObject.put("msg","第"+i+"次心跳");
System.out.println("发送心跳socket");
oos.writeObject(jsonObject);
oos.flush();
i++;
String message = ois.readUTF();
System.out.println("接收到服务端响应"+message);
if("close".equals(message)){
break;
}
}
ois.close();
oos.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
补充一下目录结构分布
是先启动springboot在启动客户端连接服务
测试输出效果
服务端打印客户端发来的业务数据消息
客户端发送消息,并且接收服务端反馈的消息打印结果
我们开了两个客户端socket一个是心跳socket一个是业务socket
我们在客户端socket敲入任意信息可以在服务端输出打印
服务端输出结果如下图
当我们在客户端输入close 时候我们就会关闭业务socket
但是不影响心跳socket继续运行
同时下次我们在开启业务socket链接可以继续向socket服务端通信
socket服务端不会中断,
实际socket长链接与我们正常开发的http协议一样,
如果服务端接收数据发现客户端发送的业务数据进行校验
如果校验不对就主动关闭客户端socket。
相关文章
暂无评论...