如何修复 python 中的 sock.recv() 阻塞状态
How to fix sock.recv() blocking state in python
我在 python 中是网络编程的新手。
我使用我在互联网上找到的连接到多播地址并接收 MPEG-TS 数据包的脚本。我在 wireshark 上看到,在 sock.setsockopt 命令之后,MPEG-TS 数据包正在到达我的计算机。
来自 wireshark 的屏幕
https://imgur.com/XJDwd61
但是当我想打印 sock.recv() 结果时出现问题。如果我正确理解文档,我相信这是因为阻塞状态。取消注释 setblocking(0) 后出现 10035 错误。
您知道我需要添加什么才能在终端中打印收到的数据吗?
提前谢谢你。
我尝试将 sock.recv() 中的 buffer_size 更改为更小、相等以及现在的状态 - 超过 1358 字节,这是单个数据报字节的数量。
import socket
import struct
import time
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
#sock.setblocking(0)
print(f"Entering while loop")
while True:
time.sleep(1)
print(f"I'm in while loop")
print(sock.recv(4096))
试试这个简单的代码,如果你愿意,你可以少设置BUFF_SIZE。
#BUFF_SIZE = 4096
BUFF_SIZE = 1024
data = b''
while True:
#chunk = s.recv(BUFF_SIZE)
#FOR UDP (@Saeed credits)
chuck = sock.recvfrom(BUFF_SIZE)
data += chunk
if len(chunk) < BUFF_SIZE:
break
print(data)
根据 How do you UDP multicast in Python? 中的示例代码,当我尝试在我的系统上 运行 它时,它工作正常。因此,我根据您的更改对其进行了更改,这是 receiver.py
代码,
import socket
import struct
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
print("Entering while loop")
while True:
print("I'm in while loop")
print(sock.recv(4096))
注意,我稍微修改了打印语句并删除了 f
,因为它会生成错误。这是 sender.py
代码,
import socket
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
sock.sendto(bytes("robot", 'UTF-8'), (MCAST_GRP, MCAST_PORT))
请注意,我正在将 robot
字符串转换为使用 UTF-8
编码的字节,因为如果使用 python3 这是必需的,而在 python2 中则不是必需的。这是我的执行结果,
如您所见,当我调用发送方时,接收方会显示 robot
字符串并循环执行 while 循环。它工作正常。
在这种情况下,如果您已经收到在 Wireshark 上显示的多播数据包,则需要确保这些数据包被发送到您正在侦听的相同端口号,即 12345
在你的情况下。如果它们被发送到不同的端口号[可能是这种情况],那么请更改您的接收器以侦听该端口号以开始接收这些数据包。
我在 python 中是网络编程的新手。 我使用我在互联网上找到的连接到多播地址并接收 MPEG-TS 数据包的脚本。我在 wireshark 上看到,在 sock.setsockopt 命令之后,MPEG-TS 数据包正在到达我的计算机。
来自 wireshark 的屏幕
https://imgur.com/XJDwd61
但是当我想打印 sock.recv() 结果时出现问题。如果我正确理解文档,我相信这是因为阻塞状态。取消注释 setblocking(0) 后出现 10035 错误。 您知道我需要添加什么才能在终端中打印收到的数据吗? 提前谢谢你。
我尝试将 sock.recv() 中的 buffer_size 更改为更小、相等以及现在的状态 - 超过 1358 字节,这是单个数据报字节的数量。
import socket
import struct
import time
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
#sock.setblocking(0)
print(f"Entering while loop")
while True:
time.sleep(1)
print(f"I'm in while loop")
print(sock.recv(4096))
试试这个简单的代码,如果你愿意,你可以少设置BUFF_SIZE。
#BUFF_SIZE = 4096
BUFF_SIZE = 1024
data = b''
while True:
#chunk = s.recv(BUFF_SIZE)
#FOR UDP (@Saeed credits)
chuck = sock.recvfrom(BUFF_SIZE)
data += chunk
if len(chunk) < BUFF_SIZE:
break
print(data)
根据 How do you UDP multicast in Python? 中的示例代码,当我尝试在我的系统上 运行 它时,它工作正常。因此,我根据您的更改对其进行了更改,这是 receiver.py
代码,
import socket
import struct
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
print("Entering while loop")
while True:
print("I'm in while loop")
print(sock.recv(4096))
注意,我稍微修改了打印语句并删除了 f
,因为它会生成错误。这是 sender.py
代码,
import socket
MCAST_GRP = '239.0.1.104'
MCAST_PORT = 12345
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
sock.sendto(bytes("robot", 'UTF-8'), (MCAST_GRP, MCAST_PORT))
请注意,我正在将 robot
字符串转换为使用 UTF-8
编码的字节,因为如果使用 python3 这是必需的,而在 python2 中则不是必需的。这是我的执行结果,
如您所见,当我调用发送方时,接收方会显示 robot
字符串并循环执行 while 循环。它工作正常。
在这种情况下,如果您已经收到在 Wireshark 上显示的多播数据包,则需要确保这些数据包被发送到您正在侦听的相同端口号,即 12345
在你的情况下。如果它们被发送到不同的端口号[可能是这种情况],那么请更改您的接收器以侦听该端口号以开始接收这些数据包。