ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot整合socket通信

2022-06-15 17:37:20  阅读:260  来源: 互联网

标签:java SpringBoot oos 整合 new import 服务端 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();
    }

}

image-20220611201538438

image-20220611201504359

三、最后

我知道,这一次挺水的,我自己都没有搞明白socket通信到底是个啥!!!

先这样记录一下吧,后续要去看网络通信的书了,沉淀是对自己最好的投资。

我是半月,祝你幸福!!!

标签:java,SpringBoot,oos,整合,new,import,服务端,socket
来源: https://www.cnblogs.com/banmoon/p/16379202.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有