关于socket的问题 “recv()函数 超时”
来源:10-2 socket 和 server 实现通信

shuaiDevelop
2019-08-23
老师,我请教一个关于socket的问题:
socket监听本地一个端口 与远程的硬件设备进行通信,发送指令并接收数据。遇到的问题是,在 data = conn.recv(1024) 接收数据,有时候(不定时)会出现 Timeout错误 ( [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败),导致程序异常退出。 捕获异常后 程序依然会退出
写回答
2回答
-
shuaiDevelop
提问者
2019-08-29
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import socket import threading import binascii import time from jpype import * import os.path import pymysql import re """1、 pip install JPype1-py3 2、 保证系统安装java环境 且java位数与python位数相等 3、 jar包与py文件处于同一目录 4、 pip install pymysql """ jar_path = os.path.join(os.path.abspath('.'), 'HexToTen.jar') data_count = 0 def tcplink(conn, addr, mysql_conn, mysql_cursor): print("Accept new connection from %s:%s" % addr) global data_count while True: try: time.sleep(2) data_count += 1 data = conn.recv(1024) if not data or len(data) <= 0: break d = binascii.b2a_hex(data) print('原始数:') print(data) # print(type(data)) s = str(d, encoding="utf-8") if s == '31': print('心跳包') print('转换后:') print(s) send_str = "030390000006E92A" send_bytes = bytes.fromhex(send_str) conn.send(send_bytes) print('蒙西发送03:') print(send_bytes) if not isJVMStarted(): startJVM(getDefaultJVMPath(), "-ea", "-Djava.class.path=%s" % jar_path) Test = JClass('gnkjtest.HexToTen') # print(Test.HexToTenFloat("43A4B50D")) temp_str = str.upper(s) try: # 03 03 0c 8cc1e449 3a750f44 e1553e40 8510 # 每间隔34位进行取数 根据返回值固定 03030c8cc1e4493a750f44e1553e408510 interval_temp_str = 34 temp_list = [temp_str[i:i+interval_temp_str] for i in range(0, len(temp_str), interval_temp_str)] for t_str in temp_list: if len(t_str) >= interval_temp_str : data_type = temp_str[0:2] if bool(re.search('[a-zA-Z]', data_type)): continue # 每隔 2 为取一次 蒙西规则 8位16进制 2位需要逆序解析 8cc1e449 :49e4c18c temp_interval_t_str = 2 temp_t_str_list = [t_str[i:i + temp_interval_t_str] for i in range(0, len(t_str), temp_interval_t_str)] # 传递给java进行16进制解析 lei_ji_i = Test.HexToTenFloat(temp_t_str_list[6] + temp_t_str_list[5] + temp_t_str_list[4] + temp_t_str_list[3]) liu_liang_f = Test.HexToTenFloat(temp_t_str_list[10] + temp_t_str_list[9] + temp_t_str_list[8] + temp_t_str_list[7]) su_du_f = Test.HexToTenFloat(temp_t_str_list[14] + temp_t_str_list[13] + temp_t_str_list[12] + temp_t_str_list[11]) # 解析后 转字符串准备存库 lei_ji_sql = str(lei_ji_i) liu_liang_sql = str(liu_liang_f) su_du_sql = str(su_du_f) print("编号: %s; 累计:%s; 流量: %s; 速度:%s" % ( data_type, lei_ji_sql, liu_liang_sql, su_du_sql)) sql_insert = "INSERT INTO BELT_SCALE_DATA(GRANDTOTAL, FLOW, SPEED, DEVICEID) VALUES (%s, %s, %s, %s);" sql_insert_real = "INSERT INTO BELT_SCALE_DATA_REAL(GRANDTOTAL, FLOW, SPEED, DEVICEID) VALUES (%s, %s, %s, %s);" sql_update_real = "UPDATE BELT_SCALE_DATA_REAL SET GRANDTOTAL=%s, FLOW=%s, SPEED=%s WHERE DEVICEID=%s;" sql_select_real = "SELECT COUNT(*) FROM BELT_SCALE_DATA_REAL WHERE DEVICEID=%s;" try: mysql_cursor.execute(sql_select_real, [data_type]) ret = mysql_cursor.fetchone() # 查询到数据 就更新 否则插入一条 if ret[0] >= 1: mysql_cursor.execute(sql_update_real, [lei_ji_sql, liu_liang_sql, su_du_sql, data_type]) else: mysql_cursor.execute(sql_insert_real, [lei_ji_sql, liu_liang_sql, su_du_sql, data_type]) # 1秒存4条 小于60s 更新到实时表 大于60s存历史表 if data_count >= 60: mysql_cursor.execute(sql_insert, [lei_ji_sql, liu_liang_sql, su_du_sql, data_type]) mysql_conn.commit() except Exception as e: print("处理mysql出错") print(e) mysql_conn.rollback() except Exception as e: print("数据解析出错") print(e) # 计数间隔 清0 if data_count >= 60: data_count = 0 if data == b"exit": conn.send(b"Good bye!\n") conn.shutdown(socket.SHUT_RDWR) conn.close() shutdownJVM() break except Exception as e: print(e) print("While 循环内部 出现异常、、") break # shutdownJVM() conn.shutdown(socket.SHUT_RDWR) conn.close() shutdownJVM() #mysql_cursor.close() #mysql_conn.close() print("Connection from %s:%s is closed" % addr) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("192.168.4.8", 5004)) s.listen(5) print("Waiting for connection...") mysql_conn = pymysql.connect(host="127.0.0.1", user="root", password="Gnkj123456", database="scales_data", charset="utf8") mysql_cursor = mysql_conn.cursor() print("mysql 数据库已连接") while True: try: conn, addr = s.accept() t = threading.Thread(target=tcplink, args=(conn, addr, mysql_conn, mysql_cursor)) t.start() except Exception as e: print(e)
00 -
bobby
2019-08-27
远程设备是一个随时处于连接状态的服务器吗?
042019-08-29
相似问题