簡體   English   中英

如何從python raw socket中的傳入數據包中獲取消息

[英]How to get message from incoming packets in python raw socket

我有2個程序(客戶端和服務器),並使用python 3編寫。

功能:

服務器程序=監視數據包

客戶端程序=發送數據包

這是服務器代碼:

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”的數據包發送到服務器。 如何解決我的代碼,以便獲得該消息並打印該消息(在服務器端只是“ Hello”)。

謝謝

其實你快到了。

udphead元組的第三個元素是UDP數據的長度。 您應該將其轉換為原始格式( socket.ntohs ),然后將其與IP頭長度和UDP頭長度一起使用,以從packet.選擇切片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數據報中,因此您可以忽略這一點)
  • 您尚未容納IP頭格式不同的IPv6。 您將需要查看version_ihl字節以進行區分。

由於您為此使用python,因此您可能需要研究scapy ,這是一個旨在方便地對網絡數據包進行編碼和解碼的庫。

對於您實際上要發送的數據包結構,是waaaayyyy overkill。 實際接收到的只是用於問候的字節,沒有額外的數據包信息。

此外,必須先將服務器綁定到IP地址/端口,然后才能開始在其上接收。

看一下本文,了解您要實現的目標。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM