Как получить сообщение от входящих пакетов в Python Raw Socket - PullRequest
0 голосов
/ 31 мая 2018

У меня есть 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"сервер.Как исправить мой код, чтобы я мог получить это сообщение и распечатать это сообщение (просто «Привет» на стороне сервера).

спасибо

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

На самом деле вы почти у цели.

Третий элемент кортежа 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)1014 * do помещается в одну дейтаграмму IP, так что вы, вероятно, можете это игнорировать)
  • Вы не включили IPv6, где заголовок IP имеет другой формат.Вам нужно взглянуть на version_ihl байт, чтобы различить.

Поскольку вы используете для этого python, вы можете захотеть взглянуть на scapy, которая является библиотекой, предназначенной для удобного кодирования идекодирование сетевых пакетов.

0 голосов
/ 31 мая 2018

То, что вы на самом деле отправляете для пакета, является избыточным.Фактическая вещь, которая принимается, это просто байты для приветствия, без дополнительной информации о пакете.

Кроме того, вы должны привязать сервер к IP-адресу / порту, прежде чем вы сможете начать получать по нему.

Взгляните на эту статью, чтобы достичь того, чего вы пытаетесь достичь.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...