如何从python原始套接字中的传入数据包中获取消息
我有两个程序客户端和服务器,使用Python3编写 功能: 服务器程序=监视数据包 客户端程序=发送数据包 这是服务器代码:如何从python原始套接字中的传入数据包中获取消息,python,python-3.x,sockets,Python,Python 3.x,Sockets,我有两个程序客户端和服务器,使用Python3编写 功能: 服务器程序=监视数据包 客户端程序=发送数据包 这是服务器代码: import socket from struct import * def PacketMonitoring(): try: sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP) except socket.error as e:
import socket
from struct import *
def PacketMonitoring():
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
except socket.error as e:
err = e.args[0]
print ("Errornya: ",e)
sys.exit()
while True:
packet = sock.recvfrom(65535)
packet = packet[0]
ip_header = packet[0:20]
iphead = unpack ("!BBHHHBBH4s4s", ip_header)
version_ihl = iphead[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iphead[5]
source_addr = socket.inet_ntoa(iphead[8])
dest_addr = socket.inet_ntoa(iphead[9])
udp_header = packet[iph_length:iph_length+8]
udphead = unpack("!HHHH",udp_header)
source_port = udphead[0]
dest_port = udphead[1]
print("\nSource IP address: ",source_addr)
print("Destination Port: ",dest_port)
print("Message: ",packet)
if __name__ == "__main__":
PacketMonitoring()
这是客户端代码:
import socket
def SendPacket(IP,Port):
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (IP, Port)
try:
clientSocket.sendto("Hello".encode(), (server_address))
print("Packet 1 send")
except:
print("Packet Failed to Send")
def Main():
IP = "192.168.67.101"
Port = 4000
SendPacket(IP,Port)
if __name__ == "__main__":
Main()
我从客户端向服务器发送包含消息Hello的数据包。如何修复我的代码,这样我就可以在服务器端获取该消息并打印该消息
感谢您实际发送的数据包结构是waaayyy overkill。实际接收的只是hello的字节,没有额外的数据包信息 此外,您必须先将服务器绑定到IP地址/端口,然后才能在其上开始接收 看一看这篇文章,以实现您想要实现的目标
事实上你就快到了 udphead元组的第三个元素是UDP数据的长度。您应该将其转换为本机格式socket.ntohs,然后将其和IP头长度和UDP头长度一起使用,以从数据包中选择一个切片。大概是这样的:
...
# Convert source address to string:
source_addr = socket.inet_ntop(socket.AF_INET, source_addr)
udp_header_length = 8
source_port = socket.ntohs(udphead[0])
dest_port = socket.ntohs(udphead[1])
udp_payload_length = socket.ntohs(udphead[2])
udp_payload_start = iph_length + udp_header_length
udp_payload = packet[udp_payload_start: udp_payload_start + udp_payload_length]
print("\nSource IP address: ", source_addr)
print("Destination Port: ", dest_port)
print("Message: ", udp_payload.decode())
以下是几点注意事项:
此处的消息假定为文本。当然,并非所有UDP数据报都由文本组成。
一个UDP数据报不需要全部放在一个IP数据包中,因此您不一定能得到全部信息。但是,当然,99%以上的UDP数据报都放在一个IP数据报中,因此您可能可以忽略这一点
您还没有适应IPv6,其中IP头具有不同的格式。您需要查看ihl字节的版本以进行区分。
由于您使用的是python,因此可能需要研究scapy,它是一个为方便地编码和解码网络数据包而设计的库 在这段代码中,我使用原始套接字。我不指定哪个端口处于活动状态。因此,使用这个原始套接字,我可以监视任何端口的每个数据包。我的问题是我如何解码那个包,这样我就可以读那个包了。感谢卡是最简单的方式