首次使用TCP长连接的记录

关于TCP长连接的服务端

转载一个地址,简单理解一下TCP长连接和短链接
https://blog.csdn.net/zxy987872674/article/details/52653101

下面直接上本次代码做记录

//TCP建立连接并接收信息service

package d1.project.sample.service;

import d1.project.sample.dao.DustDao;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author missoul
 */
@Service
public class TcpRunner implements CommandLineRunner {
    private final DustDao dustDao;
    
    public TcpRunner(DustDao dustDao) {
        this.dustDao = dustDao;
    }

    @Override
    public void run(String... args) throws Exception {
        ServerSocket server = new ServerSocket(8091);
        System.out.println("监听端口:" + 8091);
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                40,
                200,
                50,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(50),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        while (true) {
        //循环接收不同地址发来的请求,每一个请求单独拉出一个线程处理
            Socket socket = server.accept();
            pool.execute(new ServerConfig(dustDao, socket));
        }
    }
}

//代码中使用线程池对TCP长连接进行处理
//处理socket接收到的信息
package d1.project.sample.service;

import d1.project.sample.dao.DustDao;
import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * @author missoul
 */
public class ServerConfig extends Thread {
    private final DustDao dustDao;
    public Socket socket;

    public ServerConfig(DustDao dustDao, Socket socket) {
        this.dustDao = dustDao;
        this.socket = socket;
    }

    private boolean getMsg(InputStream inputStream) throws IOException {
        byte[] bytes = new byte[1024];
        int len = inputStream.read(bytes);
        if (len != -1) {
            String msg = new String(bytes, 0, len, StandardCharsets.UTF_8);
            DustService dustService = new DustService(dustDao);
            dustService.insertDustData(msg);
            return true;
        }
        return false;

    }

    private void sendMsg(OutputStream outputStream) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
        bw.write("success\n");
        bw.flush();
    }

    @Override
    public void run() {
//        try {
        // 设置连接超时9秒
        try {
            socket.setSoTimeout(120000);
            System.out.println("客户 - " + socket.getRemoteSocketAddress() + " -> 连接成功");
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();
            while (true) {
                boolean is = getMsg(inputStream);
                if (is) {
                    sendMsg(outputStream);
                }
            }
        } catch (IOException e) {
            try {
                System.out.println("异常关闭socket连接");
                socket.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }
}

关于本次使用中遇到的一些问题

1.在对接过程中,数据接收曾经一度陷入尴尬的无法接收数据问题,最终定位发现是客户端传输数据没有加上一个\n做为单次传输结束的尾标记,导致socket在接收信息的过程中一直在read,最终导致读取时间超时异常。
2.在处理socket连接的信息中,使用的是while true循环,暂时没有找到别的更好的处理方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值