Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从python原始套接字中的传入数据包中获取消息_Python_Python 3.x_Sockets - Fatal编程技术网

如何从python原始套接字中的传入数据包中获取消息

如何从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:

我有两个程序客户端和服务器,使用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()
这是客户端代码:

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,它是一个为方便地编码和解码网络数据包而设计的库

在这段代码中,我使用原始套接字。我不指定哪个端口处于活动状态。因此,使用这个原始套接字,我可以监视任何端口的每个数据包。我的问题是我如何解码那个包,这样我就可以读那个包了。感谢卡是最简单的方式