ESP8266 WiFi通信:客户端发送时间与服务器接收不符问题排查
ESP8266客户端发送时间与服务器接收不一致问题分析
问题场景
两台ESP8266通过WiFi连接,客户端负责发送本地时间,但出现客户端发送年份为2023,服务器接收却显示2000的异常。
客户端代码
def heure(): annee = str(time.localtime()[0]) mois = str(time.localtime()[1]) jour = str(time.localtime()[2]) hours = str(time.localtime()[3]) mins = str(time.localtime()[4]) if int(mins) < 10: mins = '0' + mins timestr = annee + ':' + mois + ':' + jour +':' +hours + ':' + mins return(timestr) def emission(donnees): adresse_serveur=socket.getaddrinfo("192.168.144.2",800)[0][-1] com_net=socket.socket(socket.AF_INET,socket.SOCK_STREAM) com_net.connect(adresse_serveur) com_net.send(donnees) com_net.close() timestr=heure() donnees=str(timestr) emission(donnees)
客户端打印donnees结果:2023:2:1:18:08
服务器端代码
new_list=[] conn, addr = s.accept() reception_donnees=conn.recv(512) for item in reception_donnees.split(b':'): new_list.append(item.decode('ascii')) conn.close()
服务器打印new_list结果:['2000', '1', '1', '0', '00']
问题原因
客户端本地时间未同步:ESP8266没有内置硬件RTC,重启后系统时间会默认重置到
2000-01-01 00:00:00。你看到的客户端打印2023年时间,大概率是测试时手动临时设置的时间,实际运行时客户端的time.localtime()返回的是默认初始时间,导致发送的是2000年的错误时间,服务器自然接收不到正确年份。服务器代码逻辑错误:服务器的
conn.close()写在for循环内部,这会导致接收完第一个分割字段就立刻关闭连接,后续数据无法完整接收。即使客户端发送了正确时间,也可能因为连接提前关闭导致数据截断或解析错误。
解决方法
修正客户端:添加NTP时间同步
由于ESP8266依赖系统时间,必须通过NTP同步获取正确的网络时间,代码示例:
import network import ntptime import time import socket # 连接WiFi wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect("你的WiFi名称", "你的WiFi密码") # 等待WiFi连接成功 while not wlan.isconnected(): time.sleep(1) # 同步NTP时间 try: ntptime.host = 'pool.ntp.org' # 可指定就近的NTP服务器 ntptime.settime() print("时间同步完成") except Exception as e: print("时间同步失败:", str(e)) def heure(): local_time = time.localtime() annee = str(local_time[0]) mois = str(local_time[1]) jour = str(local_time[2]) hours = str(local_time[3]) mins = str(local_time[4]) if int(mins) < 10: mins = '0' + mins timestr = f"{annee}:{mois}:{jour}:{hours}:{mins}" return timestr def emission(donnees): try: adresse_serveur = socket.getaddrinfo("192.168.144.2", 800)[0][-1] com_net = socket.socket(socket.AF_INET, socket.SOCK_STREAM) com_net.connect(adresse_serveur) # 明确编码为ASCII后发送,避免编码不一致问题 com_net.send(donnees.encode('ascii')) except Exception as e: print("发送失败:", str(e)) finally: com_net.close() timestr = heure() print("待发送时间:", timestr) emission(timestr)
修正服务器:修复连接关闭逻辑
将conn.close()移到for循环外部,确保所有数据接收解析完成后再关闭连接:
import socket # 初始化服务器Socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 800)) s.listen(1) new_list = [] conn, addr = s.accept() print("客户端连接:", addr) reception_donnees = conn.recv(512) if reception_donnees: # 分割并解码数据 for item in reception_donnees.split(b':'): new_list.append(item.decode('ascii')) # 循环结束后再关闭连接 conn.close() print("接收结果:", new_list)
内容的提问来源于stack exchange,提问作者Plub
相关产品推荐
相关产品推荐

