Domanda

pyzor usa UDP / IP come protocollo di comunicazione. Recentemente abbiamo cambiato il server pubblico per una nuova macchina, e iniziato a ricevere segnalazioni di molti timeout. Ho scoperto che ho potuto risolvere il problema se ho cambiato l'IP che è stato interrogato dal eth0:1 a eth0.

posso riprodurre questo problema con un semplice esempio:

Questo è il codice del server:

#! /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()

Questo è il codice del client (188.40.77.206 è eth0 188.40.77.236 è lo stesso server, ma è 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]

Il server riceve il pacchetto "ping" in entrambi i casi (e quindi invia il pacchetto "pong" in entrambi i casi).

Stranamente, questo ha il lavoro da alcuni posti (vale a dire che otterrà una risposta da entrambi gli IP). Per esempio, funziona da 188.40.37.137 (stessa rete / datacenter, altro server), ma anche da 89.18.189.160 (datacenter diverso). In questi casi, la risposta recvfrom ha il IP eth0, piuttosto che quello che è stato collegato.

E 'solo una regola di UDP? È questo un problema / limitazione con il href="http://python.org" rel="nofollow noreferrer"> Python classe UDPServer eth0 (o ascoltando sul IP specifico piuttosto che 0.0.0.0)?

È stato utile?

Soluzione

mi sono imbattuto in questo con un server TFTP. Il mio server aveva due indirizzi IP di fronte alla stessa rete. Perché UDP è senza connessione, non ci può essere problemi con gli indirizzi IP non essere impostati come previsto in quella situazione. La sequenza che avevo era:

  1. Il client invia il pacchetto iniziale al server in un determinato indirizzo IP
  2. Server legge l'indirizzo sorgente del client dal pacchetto in arrivo, e invia una risposta.
    1. Tuttavia, nella risposta, "indirizzo di origine" del server è impostato in base alle tabelle di routing, e viene impostata al altro l'indirizzo IP.
    2. Non è stato possibile controllare l'indirizzo IP "fonte" del server, perché il sistema operativo non ci quale indirizzo IP della richiesta ha detto entrava.
  3. Il cliente ottiene una risposta da parte del "altro" indirizzo IP e la respinge.

La soluzione nel mio caso è stato quello di legarsi in modo specifico il server TFTP all'indirizzo IP che ho voluto ascoltare, piuttosto che vincolanti per tutte le interfacce.

Ho trovato un po 'di testo che possono essere rilevanti in un href="http://man.cx/tftpd%288%29" rel="nofollow noreferrer"> pagina man tftpd (server TFTP). Eccolo:

 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.

questo risposta che dimostra che su Linux è è possibile leggere l'indirizzo locale per i pacchetti UDP, e impostare per i pacchetti in uscita. E 'possibile in C; Io non sono sicuro di Python però.

Altri suggerimenti

  

E 'solo una regola di UDP?

No.

  

È questo un problema / limitazione con il   Python UDPServer classe?

In dubbio.

  

E 'qualcosa che sto facendo in modo errato?

Il programma è corretto.

Ci sono una serie di ragioni per cui il datagramma non è sempre al server. UDP è senza connessione in modo che il cliente solo invia il ping fuori nell'etere senza sapere se qualcuno lo riceve.

Vedere se si è permesso di associare a tale indirizzo. C'è un piccolo grande programma chiamato netcat grandi opere che per l'accesso alla rete a basso livello. Non è sempre disponibili su ogni sistema, ma è facile da scaricare e compilare.

nc -l -s 188.40.77.236 -p 24440 -u

Se si esegue il programma client come prima, si dovrebbe vedere "Ping" stampata sul vostro terminale. (È possibile digitare Pong e impostare di nuovo al vostro cliente. È un po 'divertente giocare con.) Se si ottiene il ping, i problemi di rete non sono il problema e qualcosa non va con il programma server Python o librerie. Se non si ottiene il ping, non è possibile effettuare la connessione. "Per l'assistenza, contattare l'amministratore di rete".

Cose da controllare includerebbe ...

  1. problemi Firewall?
  2. problemi di configurazione con interfacce di rete alias.
  3. problemi con i permessi dell'utente.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top