Poul_EX 2026-03-17 18:25 采纳率: 0%
浏览 1

recvfrom无法接收数据

您好,本人在ESP32CAM实时显示摄像头的学习中,遇到了一个问题,在PC端和ESP32端代码都没有报错的情况下,电脑无法接收到从esp发送的数据

这是PC端

PC端
import socket
import cv2
import io
from PIL import Image
import numpy as np

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
s.bind(('0.0.0.0', 9091))
while True:
    print("成功开启")
    data, IP = s.recvfrom(100000)
    print("接收成功")
    bytes_stream = io.BytesIO(data)
    image = Image.open(bytes_stream)
    img = np.asarray(image)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)  # ESP32采集的是RGB格式,要转换为BGR(opencv的格式)
    cv2.imshow("ESP32 Capture Image", img)
    if cv2.waitKey(1) == ord("q"):
        print("退出成功")
        break

就是这个recvfrom没有接收到数据

这是ESP32端

import socket
import network
import camera
import time


# 连接wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
    print('connecting to network...')
    wlan.connect('zaishuangqi', '88888888')
    
    while not wlan.isconnected():
        pass
print('网络配置:', wlan.ifconfig())
 
 
# 摄像头初始化
try:
    camera.init(0, format=camera.JPEG)
except Exception as e:
    camera.deinit()
    camera.init(0, format=camera.JPEG)


# 其他设置:
# 上翻下翻
camera.flip(1)
#左/右
camera.mirror(1)

# 分辨率
camera.framesize(camera.FRAME_HVGA)
# 选项如下:
# FRAME_96X96 FRAME_QQVGA FRAME_QCIF FRAME_HQVGA FRAME_240X240
# FRAME_QVGA FRAME_CIF FRAME_HVGA FRAME_VGA FRAME_SVGA
# FRAME_XGA FRAME_HD FRAME_SXGA FRAME_UXGA FRAME_FHD
# FRAME_P_HD FRAME_P_3MP FRAME_QXGA FRAME_QHD FRAME_WQXGA
# FRAME_P_FHD FRAME_QSXGA
# 有关详细信息,请查看此链接:https://bit.ly/2YOzizz

# 特效
camera.speffect(camera.EFFECT_NONE)
#选项如下:
# 效果\无(默认)效果\负效果\ BW效果\红色效果\绿色效果\蓝色效果\复古效果
# EFFECT_NONE (default) EFFECT_NEG \EFFECT_BW\ EFFECT_RED\ EFFECT_GREEN\ EFFECT_BLUE\ EFFECT_RETRO

# 白平衡
# camera.whitebalance(camera.WB_HOME)
#选项如下:
# WB_NONE (default) WB_SUNNY WB_CLOUDY WB_OFFICE WB_HOME

# 饱和
camera.saturation(0)
#-2,2(默认为0). -2灰度
# -2,2 (default 0). -2 grayscale 

# 亮度
camera.brightness(0)
#-2,2(默认为0). 2亮度
# -2,2 (default 0). 2 brightness

# 对比度
camera.contrast(0)
#-2,2(默认为0).2高对比度
#-2,2 (default 0). 2 highcontrast

# 质量
camera.quality(10)
#10-63数字越小质量越高

# socket UDP 的创建
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

try:
    while True:
        buf = camera.capture()  # 获取图像数据
        s.sendto(buf, ("192.168.43.122", 9091))  # 向服务器发送图像数据
        time.sleep(0.2)
        
except:
    pass
finally:
    camera.deinit()

我使用的是手机的的热点,关闭防火墙也不行

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-03-17 18:59
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你遇到的问题是 recvfrom() 无法接收数据,这通常意味着网络通信过程中存在一些配置或连接问题。以下是一些可能的原因和解决方案,我会用加粗强调重点,并以有序列表的形式列出。


    一、确认 ESP32 和 PC 是否在同一个局域网内

    重点:确保 ESP32 和 PC 在同一个网络中(如手机热点)

    • 你使用的是手机热点,那么 ESP32 和 PC 必须连接到同一个热点
    • 如果你没有确认 IP 地址是否一致,可能会导致 sendto() 发送的数据无法被 recvfrom() 接收。

    解决方案:

    1. 检查 ESP32 的 IP 地址

      • 在 ESP32 端打印 wlan.ifconfig() 的输出,确认其 IP 地址。
      • 示例输出:('192.168.43.123', '255.255.255.0', '192.168.43.1', '8.8.8.8')
      • 你应该看到一个类似 192.168.43.x 的 IP 地址。
    2. 检查 PC 的 IP 地址

      • 打开命令提示符(Windows)或终端(Mac/Linux),运行 ipconfigifconfig 查看 PC 的 IP 地址。
      • 确保 PC 的 IP 与 ESP32 的 IP 在同一子网(如 192.168.43.x)。
    3. 确认 PC 的 IP 地址是否为 192.168.43.122

      • 你在 ESP32 代码中使用了 s.sendto(buf, ("192.168.43.122", 9091)),这是假设 PC 的 IP 是 192.168.43.122
      • 请确保你的 PC 实际 IP 确实是这个地址。

    二、确保端口正确且未被占用

    重点:确保 PC 的 9091 端口可用,且没有被其他程序占用

    • 在 PC 上运行以下命令查看 9091 端口是否监听或被占用:

    Windows:

    netstat -ano | findstr :9091
    

    Linux/Mac:

    lsof -i :9091
    
    • 如果有进程占用该端口,可以尝试更换端口号(例如将 9091 改为 9090)。

    三、确保 ESP32 代码正确发送数据

    重点:确保 ESP32 成功捕获图像并发送

    • 在 ESP32 代码中添加日志打印,确认 camera.capture() 是否返回有效数据。

    修改后的 ESP32 代码示例(添加调试信息):

    try:
        while True:
            buf = camera.capture()  # 获取图像数据
            if len(buf) > 0:
                print("发送数据大小:", len(buf))
                s.sendto(buf, ("192.168.43.122", 9091))  # 向服务器发送图像数据
            else:
                print("图像数据为空!")
            time.sleep(0.2)
            
    except:
        pass
    finally:
        camera.deinit()
    

    四、确保 PC 端的 socket 正确绑定和监听

    重点:PC 端的 socket 应该监听正确的 IP 和端口

    • 你目前的代码是:

      s.bind(('0.0.0.0', 9091))
      

      这表示 PC 监听所有网络接口的 9091 端口,这是正确的。

    • 但你可以尝试指定具体 IP 地址来测试:

      s.bind(('192.168.43.122', 9091))  # 假设 PC 的 IP 是 192.168.43.122
      

    五、确保防火墙或安全软件未阻止 UDP 通信

    重点:即使关闭了防火墙,某些安全软件也可能拦截 UDP 数据包

    • 有些系统级安全软件(如 Windows Defender)可能会限制 UDP 通信。
    • 尝试暂时禁用所有安全软件,看看是否能接收到数据。

    六、使用 Wireshark 捕获网络数据包进行调试

    重点:通过 Wireshark 确认 ESP32 是否真的发送了数据

    • 安装 Wireshark 并启动它。
    • 选择 ESP32 和 PC 所在的网络接口,过滤 udp port 9091
    • 查看是否有数据包从 ESP32 发送到 PC。

    七、修改 ESP32 代码,使用更稳定的发送方式

    重点:确保每次发送前都等待上一次发送完成

    • ESP32 可能因为图像处理速度过快而造成数据丢失,可以增加延时或使用队列机制。

    修改后的 ESP32 代码(可选):

    import time
    
    try:
        while True:
            buf = camera.capture()
            if len(buf) > 0:
                s.sendto(buf, ("192.168.43.122", 9091))
                print("已发送数据")
            time.sleep(0.2)  # 控制发送频率
    except Exception as e:
        print("发生错误:", e)
    finally:
        camera.deinit()
    

    八、确保图像格式兼容性

    重点:确保 ESP32 发送的图像格式与 PC 端解析一致

    • 你使用的是 camera.JPEG 格式,但在 PC 端使用了 Image.open(bytes_stream) 来解析。
    • 确保 ESP32 发送的是完整的 JPEG 图像数据,而不是压缩后的帧。

    九、修改 PC 端代码,增强调试能力

    重点:在 PC 端添加更多日志输出,便于排查问题

    修改后的 PC 端代码示例:

    import socket
    import cv2
    import io
    from PIL import Image
    import numpy as np
    
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    s.bind(('0.0.0.0', 9091))
    print("Socket 已绑定,等待数据...")
    
    while True:
        try:
            data, IP = s.recvfrom(100000)
            print(f"接收到来自 {IP} 的数据,长度: {len(data)}")
            bytes_stream = io.BytesIO(data)
            image = Image.open(bytes_stream)
            img = np.asarray(image)
            img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
            cv2.imshow("ESP32 Capture Image", img)
            if cv2.waitKey(1) == ord("q"):
                print("退出成功")
                break
        except Exception as e:
            print("接收异常:", e)
            break
    

    十、其他建议

    • 使用 tcpdumpWireshark 捕获网络流量,查看是否 ESP32 发送了数据。
    • 尝试使用静态 IP 地址,避免 DHCP 分配问题。
    • 尝试使用不同的设备(如笔记本电脑、台式机)作为接收端,排除硬件问题。

    总结:关键点清单

    1. 确保 ESP32 和 PC 在同一网络中,IP 地址在同一子网。
    2. 确认 PC 的 9091 端口未被占用。
    3. ESP32 代码中打印发送数据大小,确认数据有效。
    4. PC 端代码中添加日志,确认数据是否被接收。
    5. 使用 Wireshark 或 tcpdump 捕获网络数据包,判断是否发送成功。
    6. 检查防火墙或安全软件是否阻断 UDP 通信。

    如果你按照以上步骤操作后仍无法解决问题,请提供以下信息:

    • ESP32 的实际 IP 地址。
    • PC 的实际 IP 地址。
    • ESP32 代码中 wlan.ifconfig() 的输出。
    • Wireshark 中是否捕获到 ESP32 发送的数据包。

    我可以进一步帮助你分析问题根源。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月17日