python socket.recv 挂起,但是我在 tcpdump 中看到了框架
python socket.recv hangs, however I see the frame in tcpdump
我有下面的代码来发送命令,但是 python 脚本永远不会退出。它挂起。
我正在使用 RHEL 6.4 x86_64。 scapy srp1 也挂了。
from socket import *
from scapy.all import *
from myproto import *
def sendeth(REQUEST, interface = "eth0"):
"""Send raw Ethernet packet on interface."""
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind((interface, 0))
s.send(REQUEST)
data = s.recv(2048)
hexdump(data)
p = Ether()/MYPROTO()/MYPROTO1()
hexdump(p)
if __name__ == "__main__":
print "Sent %d-byte Ethernet packet on eth3" % sendeth(str(p), 'eth3')
但是执行后,我在tcpdump上看到了帧,但是python代码永远不会退出,需要一个控件^C。
tcpdump: WARNING: eth3: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth3, link-type EN10MB (Ethernet), capture size 65535 bytes
17:10:37.122445 00:00:00:00:00:00 (oui Ethernet) > Broadcast, ethertype Unknown (0x8096), length 34:
0x0000: ffff ffff ffff 0000 0000 0000 8096 0001
0x0010: 0001 1500 0000 0000 0000 0000 0000 ffff
0x0020: eafe
17:10:37.133248 00:04:25:1c:a0:02 (oui Unknown) > Broadcast, ethertype Unknown (0x8096), length 76:
0x0000: ffff ffff ffff 0004 251c a002 8096 0001
0x0010: 0001 9500 0028 0000 0000 0000 0000 0000
0x0020: 0000 f1f0 f100 0000 0000 0000 0000 0000
0x0030: 0000 0000 0000 0803 0087 1634 8096 8096
0x0040: e4f2 0000 0f21 fffc 5427 ffff
当您在套接字上调用 recv()
时,内核中的网络堆栈已经分派了您正在发送的帧,并且注意到本地主机上没有任何东西在等待它, 丢弃了它。
尝试 运行 发送方和接收方作为不同的进程。
编辑 0:
尝试将您的特定协议编号作为第三个参数添加到 socket()
。这是一个从我的 eth0
在 Debian 上抓取十个以太网帧的示例(需要 root
权限):
import socket
# from linux/if_etheer.h, all ethernet protocols, be very careful
ETH_P_ALL=0x0003
s=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind(('eth0', 0))
for n in range(10):
print n, len(s.recv(2048))
strace 在等待 select 时帮助找到了解决方案 -
解决方案是 -
from socket import *
from scapy.all import *
from myproto import *
MYPROTOTYPE = 0x8096
p = Ether()/MYPROTO()/MYPROTO1()
hexdump(p)
from socket import socket, PF_PACKET, SOCK_RAW
s = socket(PF_PACKET, SOCK_RAW, MYPROTOTYPE)
s.bind(("eth3", MYPROTOTYPE))
s.send(str(p))
data = s.recv(2048)
hexdump(data)
我有下面的代码来发送命令,但是 python 脚本永远不会退出。它挂起。 我正在使用 RHEL 6.4 x86_64。 scapy srp1 也挂了。
from socket import *
from scapy.all import *
from myproto import *
def sendeth(REQUEST, interface = "eth0"):
"""Send raw Ethernet packet on interface."""
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind((interface, 0))
s.send(REQUEST)
data = s.recv(2048)
hexdump(data)
p = Ether()/MYPROTO()/MYPROTO1()
hexdump(p)
if __name__ == "__main__":
print "Sent %d-byte Ethernet packet on eth3" % sendeth(str(p), 'eth3')
但是执行后,我在tcpdump上看到了帧,但是python代码永远不会退出,需要一个控件^C。
tcpdump: WARNING: eth3: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth3, link-type EN10MB (Ethernet), capture size 65535 bytes
17:10:37.122445 00:00:00:00:00:00 (oui Ethernet) > Broadcast, ethertype Unknown (0x8096), length 34:
0x0000: ffff ffff ffff 0000 0000 0000 8096 0001
0x0010: 0001 1500 0000 0000 0000 0000 0000 ffff
0x0020: eafe
17:10:37.133248 00:04:25:1c:a0:02 (oui Unknown) > Broadcast, ethertype Unknown (0x8096), length 76:
0x0000: ffff ffff ffff 0004 251c a002 8096 0001
0x0010: 0001 9500 0028 0000 0000 0000 0000 0000
0x0020: 0000 f1f0 f100 0000 0000 0000 0000 0000
0x0030: 0000 0000 0000 0803 0087 1634 8096 8096
0x0040: e4f2 0000 0f21 fffc 5427 ffff
当您在套接字上调用 recv()
时,内核中的网络堆栈已经分派了您正在发送的帧,并且注意到本地主机上没有任何东西在等待它, 丢弃了它。
尝试 运行 发送方和接收方作为不同的进程。
编辑 0:
尝试将您的特定协议编号作为第三个参数添加到 socket()
。这是一个从我的 eth0
在 Debian 上抓取十个以太网帧的示例(需要 root
权限):
import socket
# from linux/if_etheer.h, all ethernet protocols, be very careful
ETH_P_ALL=0x0003
s=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind(('eth0', 0))
for n in range(10):
print n, len(s.recv(2048))
strace 在等待 select 时帮助找到了解决方案 - 解决方案是 -
from socket import *
from scapy.all import *
from myproto import *
MYPROTOTYPE = 0x8096
p = Ether()/MYPROTO()/MYPROTO1()
hexdump(p)
from socket import socket, PF_PACKET, SOCK_RAW
s = socket(PF_PACKET, SOCK_RAW, MYPROTOTYPE)
s.bind(("eth3", MYPROTOTYPE))
s.send(str(p))
data = s.recv(2048)
hexdump(data)