SpringBoot整合socket通信
SpringBoot整合socket通信
一、介绍#
很多人都不太理解socket
通信指的是什么,简单来讲,它是一个完成两个应用程序之间的数据传输的东西。
socket
是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,一个socket
就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,socket
上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。
本次使用Java
语言去实现socket
通信,用的SpringBoot
框架,当然直接使用main
方法启用也是没有问题的。
推荐访问:个人博客
二、实现#
1)服务端#
先设置一下需要用到的配置,主要就是这个端口号,我觉得放配置文件中会比较好
socket-port: testSocket: 2333
socket
服务端启动类
此处使用到了bean
的初始化,如果不熟悉的话,使用静态代码块也是一样的
package com.banmoon.test.socket; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; 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; @Slf4j @Component("testSocket") public class TestSocketStart { @Value("${socket-port.testSocket}") private Integer port; public static ServerSocket testSocket = null; private static final ThreadPoolExecutor testSocketThreadPool = new ThreadPoolExecutor(15, 15, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); @PostConstruct public void start() { new Thread(() -> { try { testSocket = new ServerSocket(port); log.info("socket服务端开启"); while (true){ Socket socket = testSocket.accept(); testSocketThreadPool.execute(new TestSocketService(socket)); } } catch (IOException e) { log.info("socket服务启动异常"); e.printStackTrace(); } }, "testSocket").start(); } }
具体socket
服务类,此类用来处理业务消息,同时这个一个多线程类
package com.banmoon.test.socket; import cn.hutool.json.JSONObject; import com.banmoon.test.dto.ResultData; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; @Slf4j @AllArgsConstructor public class TestSocketService implements Runnable{ private Socket socket; @Override @SneakyThrows public void run() { ObjectInputStream ois = null; ObjectOutputStream oos = null; try { // 输入流接收数据 ois = new ObjectInputStream(socket.getInputStream()); // 输出流发送数据 oos = new ObjectOutputStream(socket.getOutputStream()); JSONObject jsonObject = (JSONObject) ois.readObject(); log.info("模拟处理业务:{}", jsonObject); // 输出流发送返回参数 JSONObject resultJson = new JSONObject(ResultData.success()); oos.writeUTF(resultJson.toString()); oos.flush(); } catch (Exception e) { log.info("接收数据异常socket关闭"); e.printStackTrace(); } finally { // 关闭流 oos.close(); ois.close(); socket.close(); log.info("关闭流成功" + System.lineSeparator()); } } }
服务端编写完毕,剩下就是在客户端了,我们该如何调用?
2)客户端#
客户端这边的类,实现了一个Callable
接口,使其变成一个有返回值的多线程类。
package com.banmoon.test; import cn.hutool.json.JSONObject; import lombok.AllArgsConstructor; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.concurrent.Callable; @AllArgsConstructor public class TestSocketClientService implements Callable<String> { private JSONObject paramJson; @Override public String call() throws Exception { Socket socket = null; ObjectInputStream ois = null; ObjectOutputStream oos = null; try { socket = new Socket("127.0.0.1", 2333); // 输出流写数据 oos = new ObjectOutputStream(socket.getOutputStream()); // 输入流读数据 ois = new ObjectInputStream(socket.getInputStream()); // 输出流给服务端发送数据 oos.writeObject(paramJson); oos.flush(); // 输入流接收服务端返回的数据 String message = ois.readUTF(); return message; } catch (IOException e) { e.printStackTrace(); return null; } finally { ois.close(); oos.close(); socket.close(); } } }
当然,此处写的比较简陋,注意客户端和服务端发送、读取信息时需要相同的编码。
3)测试#
服务端,客户端都有了,我们该如何发起通信?
首先,我们先启用SpringBoot
服务端,启动完成后再对客户端进行使用
如下,我们只需要创建线程,把paramJson
传入,启用这个线程,就能够发送数据了。
package com.banmoon.test; import cn.hutool.json.JSONObject; import com.banmoon.test.dto.UserDTO; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import java.util.concurrent.*; @Slf4j public class SomethingTest { @Test public void test() throws InterruptedException, ExecutionException { ExecutorService service = Executors.newFixedThreadPool(1); for (int i = 0; i < 5; i++) { JSONObject paramJson = new JSONObject(new UserDTO("半月无霜", "男", 18+i)); Future<String> future = service.submit(new TestSocketClientService(paramJson)); log.info("服务端返回的参数:{}", future.get()); TimeUnit.SECONDS.sleep(2); } service.shutdown(); } }
三、最后#
我知道,这一次挺水的,我自己都没有搞明白socket
通信到底是个啥!!!
先这样记录一下吧,后续要去看网络通信的书了,沉淀是对自己最好的投资。
我是半月,祝你幸福!!!
作者: 半月无霜
出处:https://www.cnblogs.com/banmoon/p/16379202.html
本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战