문제

Pyzor UDP/IP를 통신 프로토콜로 사용합니다. 우리는 최근에 공개 서버를 새로운 컴퓨터로 전환하고 많은 타임 아웃에 대한보고를 시작했습니다. 쿼리 된 IP를 변경하면 문제를 해결할 수 있음을 발견했습니다. eth0:1 에게 eth0.

간단한 예로이 문제를 재현 할 수 있습니다.

이것은 서버 코드입니다.

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

이것은 클라이언트 코드입니다 (188.40.77.206 ~이다 eth0. 188.40.77.236 동일한 서버이지만 그렇습니다 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]

서버는 두 경우 모두 "Ping"패킷을 가져옵니다 (따라서 두 경우 모두 "Pong"패킷을 보냅니다).

이상하게도, 이것 하다 일부 장소에서 일하십시오 (즉, 두 IP로부터 응답을받을 것입니다). 예를 들어, 작동합니다 188.40.37.137 (동일한 네트워크/데이터 센터, 다른 서버). 89.18.189.160 (다른 데이터 센터). 그 경우 recvfrom 응답에는 다음과 같습니다 eth0 연결된 것보다 IP.

이것은 단지 UDP의 규칙입니까? 이것은 문제/제한입니까? 파이썬 UDPServer 수업? 내가 잘못하고있는 일인가요? 단순히 연결하는 것 외에이 작업을 수행 할 수있는 방법이 있습니까? eth0 IP (또는 또는 0.0.0.0)?

도움이 되었습니까?

해결책

TFTP 서버로 이것을 발견했습니다. 내 서버에는 동일한 네트워크에 직면 한 두 개의 IP 주소가 있습니다. UDP는 연결이 없기 때문에 해당 상황에서 예상대로 설정되지 않은 IP 주소에 문제가있을 수 있습니다. 내가 가진 순서는 다음과 같습니다.

  1. 클라이언트는 초기 패킷을 특정 IP 주소로 서버로 보냅니다.
  2. 서버는 들어오는 패킷에서 클라이언트의 소스 주소를 읽고 응답을 보냅니다.
    1. 그러나 응답에서 서버의 "소스 주소"는 라우팅 테이블에 따라 설정되며 다른 IP 주소.
    2. OS가 요청이 어떤 IP 주소로 들어온지 알려주지 않았기 때문에 서버의 "소스"IP 주소를 제어 할 수 없었습니다.
  3. 클라이언트는 "기타"IP 주소로부터 응답을 받고 거부합니다.

내 경우 솔루션은 TFTP 서버를 모든 인터페이스에 바인딩하기보다는 듣고 싶은 IP 주소에 구체적으로 바인딩하는 것이 었습니다.

나는 Linux Man 페이지 tftpd (TFTP 서버). 여기있어:

 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.

보다 이 답변 Linux에서 그것을 보여줍니다 ~이다 들어오는 UDP 패킷의 로컬 주소를 읽고 나가는 패킷으로 설정할 수 있습니다. C에서 가능합니다. 그래도 파이썬에 대해 잘 모르겠습니다.

다른 팁

이것은 단지 UDP의 규칙입니까?

아니.

Python udpserver 클래스의 문제/제한입니까?

불안한.

내가 잘못하고있는 일인가요?

귀하의 프로그램이 정확해 보입니다.

데이터 그램이 서버에 들어 가지 않는 데는 여러 가지 이유가 있습니다. UDP는 연결이 없으므로 클라이언트는 누군가가받는 지 알지 못하고 핑을 에테르로 보냅니다.

해당 주소에 결합 할 수 있는지 확인하십시오. 낮은 레벨 네트워크 액세스에 적합한 NetCat이라는 훌륭한 작은 프로그램이 있습니다. 모든 시스템에서 항상 사용할 수있는 것은 아니지만 다운로드하고 컴파일하기 쉽습니다.

nc -l -s 188.40.77.236 -p 24440 -u

이전과 같이 클라이언트 프로그램을 실행하는 경우 터미널에 "Ping"이 인쇄되어야합니다. (Pong을 입력하고 고객에게 다시 설정할 수 있습니다. 함께 플레이하는 것은 재미 있습니다.) Ping을 받으면 네트워킹 문제가 문제가되지 않으며 Python Server 프로그램이나 라이브러리에 문제가 있습니다. 핑을 얻지 못하면 연결할 수 없습니다. "도움을 받으려면 네트워크 관리자에게 문의하십시오."

확인해야 할 사항은 ...

  1. 방화벽 문제?
  2. 별칭 네트워크 인터페이스의 구성 문제.
  3. 사용자 권한 문제.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top