Frage

Pyzor verwendet UDP / IP als Kommunikationsprotokoll. Wir schalteten vor kurzem den öffentlichen Server auf eine neue Maschine und begann Berichte über viele Timeouts bekommen. Ich entdeckte, dass ich konnte das Problem beheben, wenn ich die IP geändert, die von eth0:1 zu eth0 abgefragt wurde.

ich dieses Problem mit einem einfachen Beispiel wiedergeben kann:

Dies ist der Server-Code:

#! /usr/bin/env python

import SocketServer

class RequestHandler(SocketServer.DatagramRequestHandler):
    def handle(self):
        print self.packet
        self.wfile.write("Pong")

s = SocketServer.UDPServer(("0.0.0.0", 24440), RequestHandler)
s.serve_forever()

Dies ist der Client-Code (188.40.77.206 ist eth0 188.40.77.236 die gleichen Server, aber ist eth0:1.):

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.206", 24440))
4
>>> s.recvfrom(1024)
('Pong', ('188.40.77.206', 24440))
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.236", 24440))
4
>>> s.recvfrom(1024)
[never gets anything]

Der Server erhält das "Ping" Paket in beiden Fällen (und daher sendet das "Pong" Paket in beiden Fällen).

Merkwürdig ist, dass diese funktioniert Arbeit von einigen Stellen (d werde ich eine Antwort von den beiden IP-Adressen erhalten). Zum Beispiel arbeitet es aus 188.40.37.137 (gleichem Netzwerk / Rechenzentrum, andere Server), sondern auch von 89.18.189.160 (verschiedenen Rechenzentrum). In diesen Fällen hat die recvfrom Antwort die eth0 IP, anstatt der einen, die verbunden war.

Ist das nur eine Regel des UDP? Ist das ein Problem / Einschränkung mit der Python UDPServer Klasse? Ist es etwas, was ich falsch tue? Gibt es eine Möglichkeit, dass ich diese Arbeit neben einfach eine Verbindung zum eth0 IP (oder das Hören auf der spezifischen IP anstatt 0.0.0.0) haben kann?

War es hilfreich?

Lösung

Ich kam in diesen mit einem TFTP-Server. Mein Server hatte zwei IP-Adressen das gleiche Netzwerk gegenüber. Da UDP verbindungslos ist, kann es Probleme mit IP-Adressen, die nicht wie erwartet in dieser Situation eingestellt werden. Die Folge ich hatte, war:

  1. Client sendet das erste Paket an den Server zu einer bestimmten IP-Adresse
  2. Server liest das Quelle-Adresse des Clients aus dem eingehenden Paket und sendet eine Antwort.
    1. jedoch in der Antwort, der „Quelladresse“ des Servers wird gemäß den Routing-Tabellen festgelegt, und es auf die andere gesetzt wird IP-Adresse.
    2. Es war nicht möglich, die „Quelle“ IP-Adresse des Servers zu kontrollieren, weil das Betriebssystem nicht sagen, hat uns die IP-Adresse die Anfrage kam durch.
  3. Der Kunde erhält eine Antwort von der „anderen“ IP-Adresse und lehnt sie ab.

Die Lösung in meinem Fall war, um speziell den TFTP-Server die IP-Adresse zu binden, die ich als die Bindung an alle Schnittstellen, sondern hören wollte.

fand ich einen Text, der in einer Linux-man-Seite für tftpd (TFTP-Server). Hier ist sie:

 Unfortunately, on multi-homed systems, it is impossible for tftpd to
 determine the address on which a packet was received. As a result, tftpd
 uses two different mechanisms to guess the best source address to use for
 replies. If the socket that inetd(8) passed to tftpd is bound to a par‐
 ticular address, tftpd uses that address for replies. Otherwise, tftpd
 uses ‘‘UDP connect’’ to let the kernel choose the reply address based on
 the destination of the replies and the routing tables. This means that
 most setups will work transparently, while in cases where the reply
 address must be fixed, the virtual hosting feature of inetd(8) can be
 used to ensure that replies go out from the correct address.  These con‐
 siderations are important, because most tftp clients will reject reply
 packets that appear to come from an unexpected address.

Siehe href="https://stackoverflow.com/a/3929208/60075">, die auf Linux zeigt, dass es ist möglich, die lokale Adresse zu lesen für eingehende UDP-Pakete, und setzte es für ausgehende Pakete. Es ist möglich, in C; Ich bin nicht sicher über Python though.

Andere Tipps

  

Ist das nur eine Regel des UDP?

Nein.

  

Ist das ein Problem / Einschränkung der   Python UDPServer Klasse?

Doubtful.

  

Ist es etwas, was ich falsch tue?

Ihr Programm sieht richtig.

Es gibt eine Reihe von Gründen, warum das Datagramm ist nicht auf den Server zu bekommen. UDP ist verbindungslos, so dass Ihre Client sendet nur den Ping in den Äther ab, ohne zu wissen, ob jemand sie empfängt.

Sehen Sie, wenn Sie an diese Adresse zu binden, sind erlaubt. Es ist ein großartiges kleines Programm namens netcat, die für geringen Netzwerkzugriff funktioniert gut. Es ist nicht immer auf jedem System zur Verfügung, aber es ist einfach herunterzuladen und zu kompilieren.

nc -l -s 188.40.77.236 -p 24440 -u

Wenn Sie Ihr Client-Programm wie vor ausführen, sollten Sie „Ping“ gedruckt auf Ihrem Terminal sehen. (Sie können Pong geben und es zurück zu Ihrem Client festgelegt. Es ist ein bisschen Spaß zu spielen.) Wenn Sie den Ping erhalten, sind die Netzwerkprobleme nicht das Problem und ist etwas falsch mit dem Python-Server-Programm oder Bibliotheken. Wenn Sie nicht über den Ping erhalten, können Sie nicht die Verbindung herzustellen. „Kontaktieren Sie Ihren Netzwerkadministrator um Hilfe.“

Die Dinge würden gehören zu überprüfen ...

  1. Firewall Probleme?
  2. Konfiguration Probleme mit aliased Netzwerk-Schnittstellen.
  3. Benutzerberechtigungsprobleme.
scroll top