在pythonraw中如何从传入数据包中获取消息

2024-10-02 08:18:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有2个程序(客户机和服务器)并用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:
        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()

这是客户代码:

^{pr2}$

我从客户端向服务器发送包含“Hello”消息的包。如何修复我的代码,这样我就可以获得该消息并打印该消息(在服务器端只需“Hello”)。在

谢谢


Tags: 代码sourcepacketportversionsocketlengthdest
2条回答

因为你实际发送的数据包的结构是waaayyyy-overkill。实际接收到的只是hello的字节,没有额外的数据包信息。在

此外,您必须将服务器绑定到IP地址/端口,然后才能开始接收。在

看一看这篇文章,以实现您想要实现的目标。在

https://wiki.python.org/moin/UdpCommunication

实际上你就快到了。在

udphead元组的第三个元素是UDP数据的长度。您应该将其转换为本机格式(socket.ntohs),然后将其与IP报头长度和UDP报头长度一起使用,从packet.中选择一个片段,如下所示:

...
# 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,在IPv6中,IP报头有不同的格式。您需要查看version_ihl字节来区分。在

由于您正在使用python实现这一点,您可能需要研究一下scapy,这是一个为方便地编码和解码网络包而设计的库。在

相关问题 更多 >

    热门问题