【问题标题】:Python sendto doesn't seem to sendPython sendto 似乎没有发送
【发布时间】:2015-07-09 04:46:42
【问题描述】:

我是 Python 新手,并尝试使用套接字将字节数组作为原始数据包发送。我的 IP 是 192.168.0.116,我要发送到的设备是 192.168.0.64。这个客户端设备是一个基于微控制器的单元,它正在执行我的代码以简单地嗅探以太网数据包并检查特定模式。我正在使用 UDP 数据包,并通过在我的 PC 中使用“Ostinato”来尝试客户端固件来发送原始 UDP 数据包。我正在使用 Wireshark 来监控网络数据包流。客户端似乎可以很好地处理 Ostinato 发送的数据包。

但是,当我尝试使用 Python 发送相同的数据包(使用如下原始数据包)时,它似乎没有吐出字节,因为我在 Wireshark 上看不到任何内容,客户端也没有获得任何数据。但是sendto() 的返回值是正确的。因此,Python 似乎将字节数组提供给要发送的缓冲区(由操作系统?)但停在那里。

import socket
CLNT_UDP_IP = '192.168.0.64'
CLNT_UDP_PORT = 5005
svr_sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

send_data = [0x00, 0x11...]
send_data_arr = bytearray (send_data)
svr_sock.bind (('192.168.0.116',0))  
bytes_send = svr_sock.sendto (send_data_arr, (CLNT_UDP_IP, CLNT_UDP_PORT))
svr_sock.close()

为了清楚起见,我已经删除了 try-except 块。

我注意到的另一件事是,当套接字关闭时,它需要一些时间。如果我注释掉 sendto 语句,它会立即退出。所以看起来套接字关闭正在尝试刷新发送缓冲区,但发送数据包失败。

有什么想法吗?

【问题讨论】:

  • 我认为如果你想要 UDP,你应该使用 socket.SOCK_DGRAM 和 socket.IPPROTO_UDP 套接字类型。否则你必须手动创建数据包头。
  • 感谢 Ilya,我第一次尝试使用 UDP 并有相同的行为。然后我认为'sendto'可能依赖于来自从站的一些额外信息,它没有响应。 (当我将其发送到另一台计算机时,它可以工作)这就是我尝试原始数据的原因。缓冲区“send_data[]”包含我已经使用 Ostinato 验证过的完整以太网数据包。

标签: python sockets networking


【解决方案1】:
  1. Ilya 是对的,你应该打开一个 UDP 套接字

    socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

  2. 您正在绑定到端口 0,这是无效的。如果这不是入站端口,则不需要绑定它。这可以解释为什么您的 sendto 调用被阻塞了。

  3. send_data 数组应该只包含您的数据,而不是“完整的以太网数据包”。

  4. send_data 数组必须小于网络的 MTU 大小,否则它可能会被静默丢弃。它各不相同,但低于 1300 应该可以工作,超过 1500 几乎肯定不会工作。

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 1970-01-01
    • 2022-09-23
    • 2016-07-30
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多