tcp接发json字符串

因工作需要对接硬件设备,需要通过tcp协议接收发送字符串,而字符串里面全是json字符串,登陆用json对象发送,心跳也用json发送,设备检测到信号后自动推送的也是json字符串,只要登陆后心跳就要每过10秒发送一次,而信号的推送则是在登陆后的任意时间发生.每个json与json之间没有换行符分割,所以让deepseek帮着写了能读取嵌套json的解析代码.

因为是个小工具,因此选择python编写,核心代码如下:

python 复制代码
import socket 
import json 
import time 
import threading 


class TCPClient:
    def __init__(self, host='127.0.0.1', port=60, fun_exec=None):
        print(f"host={host} port={port}")
        self.host  = host 
        self.port  = port 
        self.client_socket  = None 
        self.heartbeat_interval  = 10  # 心跳间隔10秒 
        self.is_running  = False 
        self.buffer  = "" 
        self.fun_exec = fun_exec
        
    def connect(self):
        """建立TCP连接并发送登录信息"""
        try:
            # 创建TCP套接字 
            self.client_socket  = socket.socket(socket.AF_INET,  socket.SOCK_STREAM)
            # 设置超时时间(单位:秒)
            self.client_socket.settimeout(100)
            # 连接服务器 
            try:
                print('开始连接')
                self.client_socket.connect((self.host,  self.port)) 
                print(f"已连接") 
            except socket.timeout: 
                print("连接超时,请检查网络或服务器状态")
                return False
            except Exception as e:
                print(f"连接失败: {str(e)}")
                return False
            
            # 发送登录信息 
            login_data = {
                "cmd": "1",
                "username": "账号",
                "password": "密码"
            }
            self._send_json(login_data)
            return True 
        except Exception as e:
            print(f"连接失败: {str(e)}")
            return False 
 
    def _send_json(self, data):
        """发送JSON数据"""
        try:
            json_str = json.dumps(data)
            # print(f"发送信息:{data}")
            self.client_socket.sendall(json_str.encode('utf-8')) 
        except Exception as e:
            print(f"发送数据失败: {str(e)}")
            self.reconnect() 
 
    def _heartbeat_task(self):
        """心跳维持线程"""
        if 'all' == global_leida_log:
            print('开始发送心跳')
        while self.is_running: 
            heartbeat_data = {
                "cmd": "2"
            }
            self._send_json(heartbeat_data)
            time.sleep(self.heartbeat_interval) 
 
    def _process_message(self, message):
        """处理接收到的JSON消息"""
        try:
            data = json.loads(message) 
            print(f"收到服务器响应: {data}")
            self.fun_exec(data)
        except json.JSONDecodeError:
            print("收到无效的JSON数据")
 
    def reconnect(self):
        """断线重连机制"""
        self.stop() 
        print("尝试重新连接...")
        while True:
            if self.connect(): 
                self.start() 
                break 
            time.sleep(5) 
 
    def start(self):
        """启动客户端服务"""
        self.is_running  = True 
        # 启动心跳线程 
        threading.Thread(target=self._heartbeat_task, daemon=True).start()
        # 启动接收线程 
        threading.Thread(target=self._receive_handler, daemon=True).start()
 
    def stop(self):
        """停止客户端"""
        self.is_running  = False 
        if self.client_socket: 
            try:
                self.client_socket.close() 
            except:
                pass 
 
    def _receive_handler(self): 
        """接收数据处理器"""
        # print('开始接收数据:')
        while self.is_running: 
            try: 
                data = self.client_socket.recv(4096)  
                if not data: 
                    print("连接已断开") 
                    self.reconnect()  
                    break 
 
                self.buffer  += data.decode('utf-8')  
 
                # 处理缓冲区中的数据 
                while self.buffer:  
                    try: 
                        # 尝试解析 JSON 对象 
                        obj, end_index = self._parse_json(self.buffer)  
                        if obj is not None: 
                            # 处理解析后的 JSON 对象 
                            self._process_message(json.dumps(obj))  
                            # 移除已处理的数据 
                            self.buffer  = self.buffer[end_index:].lstrip()  
                        else: 
                            break 
                    except json.JSONDecodeError: 
                        break 
 
            except Exception as e: 
                print(f"发生错误: {e}") 

    def _parse_json(self, data): 
        stack = [] 
        start_index = None 
        for i, char in enumerate(data): 
            if char == '{': 
                if not stack: 
                    start_index = i 
                stack.append(char)  
            elif char == '}': 
                if stack: 
                    stack.pop()  
                    if not stack: 
                        try: 
                            json_obj = json.loads(data[start_index:i  + 1]) 
                            return json_obj, i + 1 
                        except json.JSONDecodeError: 
                            pass 
        return None, 0 
 

def temp_fun(d):
    print(d)


if __name__ == "__main__":
    client = TCPClient(host='192.168.0.6', port=60, fun_exec=temp_fun)
    if client.connect(): 
        try:
            client.start() 
            # 保持主线程运行 
            while True:
                time.sleep(1) 
        except KeyboardInterrupt:
            client.stop() 
相关推荐
I疯子几秒前
2026-04-13 打卡第 6 天
开发语言·python
HaiXCoder几秒前
python从入门到精通-第6章: 元编程 — Python的"超能力"
python
素玥6 分钟前
实训7 json文件数据用python导入数据库
数据库·python·json
千枫s6 分钟前
做一个电脑版爬虫程序
爬虫·python
大邳草民6 分钟前
Python 对象模型与属性访问机制
开发语言·笔记·python
weixin_4024863410 分钟前
小分子 pdb准化为sdf
python
橘子编程11 分钟前
密码学完全指南:从基础到实战
java·python·密码学
蓝色的杯子11 分钟前
Python面试30分钟突击掌握-LeetCode2-Strings
python
ZC跨境爬虫13 分钟前
海南大学交友平台开发实战 day9(头像上传存入 SQLite+BLOB 存储 + 前后端联调避坑全记录)
前端·数据库·python·sqlite
FreakStudio13 分钟前
嘉立创开源:应该是全网MicroPython教程最多的开发板
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy