Java TCP 客户端

230 阅读1分钟

Java TCP客户端,自带心跳,断线重连

@Slf4j
public class TcpClient extends Thread {
    public static String host = "127.0.0.1";
    public static int port = 1234;
    public static Socket client = null;
    public static InputStream in = null;
    public static OutputStream out = null;

    public TcpClient(Socket socket) {
        this.client = socket;
        try {
            in = socket.getInputStream();
            out = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("TcpClient {}", stackTraceToString(e));
        }
    }

    @Override
    public void run() {
        try {
            while (!isInterrupted()) {
                try {
                    if (client.isClosed() || in == null) {
                        out = null;
                        client = null;
                        this.interrupt();
                        break;
                    }
                    int available = in.available();
                    if (available > 0) {
                        byte[] buffer = new byte[available];
                        int size = in.read(buffer);
                        if (size > 0) {
                            String data = new String(buffer, 0, buffer.length).trim();
                            log.info("我是获取到的数据 {} ", data);
                            try {
                                //分析数据
                                SpringUtils.getBean(UdpPowerServiceImpl.class).udpHandleMethod(data);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        } else {
                            log.info("读取数据失败");
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error("TcpClient run {}", stackTraceToString(e));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送消息出去
     *
     * @param msg
     */
    public static void sendTcpMsg(String msg) {
        try {
            if (client != null && !client.isClosed() && out != null) {
                out.write(msg.getBytes("UTF-8"));
                out.flush();
            } else {
                connectAlways();
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (client != null) {
                try {
                    client.close();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
            client = null;
            log.error("sendTcpMsg run {}", stackTraceToString(e));
        }
    }

    /**
     * 掉线重连
     */
    public static void connectAlways() {
        try {
            if (client == null || client.isClosed()) {
                client = new Socket(host, port);//socket连接建立
                log.info("Tcp Connect Success host {}, port {}", host, port);
                TcpClient clientThread = new TcpClient(client);//客户端线程
                clientThread.start();//启动客户端
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Tcp Connect error host {}, port {} msg {}", host, port, stackTraceToString(e));
        }
    }

    /**
     * 开启TCP监听
     */
    public static void startTcp(String host, int port) {
        TcpClient.host = host;
        TcpClient.port = port;
        //这个启动很有意思 自带心跳检测
        CThreadPoolExecutor.runInBackground(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        sendTcpMsg("");
                        //掉线后 每30秒检测发送心跳检测一下 掉线自动重连
                        Thread.sleep(1000 * 30);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public static void main(String[] args) {
        while (true) {
            try {
                sendTcpMsg("Connect Heart");
                //掉线后 每30秒检测发送心跳检测一下 掉线自动重连
                Thread.sleep(1000 * 5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}