SpringBoot+SOCKET服务端客户端

2年前 (2022) 程序员胖胖胖虎阿
237 0 0

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在启动客户端连接服务
SpringBoot+SOCKET服务端客户端

测试输出效果

服务端打印客户端发来的业务数据消息
SpringBoot+SOCKET服务端客户端
SpringBoot+SOCKET服务端客户端
客户端发送消息,并且接收服务端反馈的消息打印结果
我们开了两个客户端socket一个是心跳socket一个是业务socket
我们在客户端socket敲入任意信息可以在服务端输出打印

SpringBoot+SOCKET服务端客户端
服务端输出结果如下图
SpringBoot+SOCKET服务端客户端
当我们在客户端输入close 时候我们就会关闭业务socket
但是不影响心跳socket继续运行
同时下次我们在开启业务socket链接可以继续向socket服务端通信
socket服务端不会中断,

实际socket长链接与我们正常开发的http协议一样,
如果服务端接收数据发现客户端发送的业务数据进行校验
如果校验不对就主动关闭客户端socket。

版权声明:程序员胖胖胖虎阿 发表于 2022年9月26日 上午8:24。
转载请注明:SpringBoot+SOCKET服务端客户端 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...