2013-07-31 2 views
0

저는 Python 2.7 (Geany IDE 사용)에서 몇 달 동안 기본 채팅 응용 프로그램을 사용하려고 시도해 왔으며 결국 UDP를 사용하여 작동하는 기본 응용 프로그램을 얻었습니다. 연결할 수 있고 통신을 브로드 캐스트 할 수 있지만 클라이언트가 연결 한 다음 나중에 닫으면 다음 번에 모든 클라이언트에 메시지를 브로드 캐스팅하려고 할 때 서버가 충돌합니다. 문제는 그것이 무슨 일이 일어나고 있는지 정확하게 알 수 없기 때문에 오류 메시지 나 추적 코드를 반환하지 않고 충돌한다는 것입니다. 다음은 코드입니다 (이는 클라이언트의 getch() 코드로 인해 창에서만 작동합니다).Python UDP sendto() 예외 블록 무시 및 충돌

서버 :

from socket import * 
s = socket(AF_INET,SOCK_DGRAM) 
s.bind(("25.150.175.48",65437)) 
maxsize = 4096 
listeners = [] 
while True: 
    data, addr = s.recvfrom(maxsize) 
    if addr not in listeners: 
     listeners.append(addr) 
     #print addr[1] 
     print "new client added from %s on port %i" % (addr[0],addr[1]) 
    for l in listeners: 
     try: 
      s.sendto(data,l) 
     except: 
      listeners.remove(l) 

클라이언트 :

from socket import * 
import select 
import msvcrt 
s = socket(AF_INET,SOCK_DGRAM) 
s.bind(("25.150.175.48",65438))#change port to 65439 for the second client 
maxsize = 4096 
waitseconds = 0.001 
server = ("25.150.175.48",65437) 
s.sendto(raw_input(">"),server) 
while True: 
    ready = select.select([s], [], [], waitseconds) 
    if ready[0]: 
     data = s.recv(maxsize) 
     print data 
    else: 
     if msvcrt.kbhit(): 
      char = msvcrt.getch() 
      if char == "\r": 
       s.sendto(raw_input(">"),server) 

내 이론은 내가 서버가 사람이 클라이언트를 닫을 때 인식 할 수 있다면, 나는 목록에서 클라이언트 주소를 제거 할 수 있다는 것입니다 청취자가 잘 작동합니다. 불행히도 제대로 작동하지 않고 서버가 연결을 확인하는 데 사용할 수있는 일종의 테스트 패킷을 보내는 방법을 모르겠습니다. 인터넷에서 읽은 모든 예는 포트가 존재하는지 확인하는 것 같습니다. 누군가이 문제를 처리하는 방법에 대해 알고 있다면, 도움을 크게 주시면 감사하겠습니다.

편집 : 나는 마침내 IDLE에서 서버 프로그램을 실행하여 역 추적을받을 수 관리

조금 주위 공구 후. 다음과 같이 추적은 다음과 같습니다 (? 나는 심각하게 걱정 어느, 파이썬 버그) 문 내가 그것을 실행할 때이를 잡으려고 실패 할 것 같다 제외하고

Traceback (most recent call last): 
    File "G:\Python\Miscellaneous\Examples\UDP Chat Server & Client\UDP server.py", line 7, in <module> 
    data, addr = s.recvfrom(maxsize) 
error: [Errno 10054] An existing connection was forcibly closed by the remote host 

나는/내 시도,이 처리 약간의 도움이 필요합니다. 이 추적을 반환하면 프로그램이 종료됩니다. 어떤 제안?

+0

추적 back은 sendto() 호출이 아닌 recvfrom() 호출에서 예외를 보여줍니다. 어쩌면 거기에 try 블록을 넣고 예외를 인쇄하십시오. 그런 다음 무시하고 처리 할 수 ​​있습니다. – pcm

+0

예상대로 예외가 인쇄되지만 현재이 문제를 처리하는 방법을 알지 못합니다. 클라이언트가 강제로 닫히는 코드를 반환 할 수있는 방법이 있습니까? 또는 적어도 IP? –

+0

계속 http://stackoverflow.com/questions/17984610/python-error-10054-client-forcibly-closed-get-ip-of-error –

답변

0

try \ except 블록을 사용하면 추적을받지 못합니다. 당신이하는 일을 정말로 알지 못한다면 그런 오류를 무시하면 안됩니다.

try: 
    s.sendto(data,l) 
except Exception as e: 
    print(e) 
    listeners.remove(l) 

크래시는 말하기 어렵습니다. UDP는 연결 지향이 아니므로 클라이언트가 실행 중이거나 실행되지 않아서 서버가 손상되거나 패키지 전송이 중단되지 않아야합니다.

UDP를 독점적으로 사용하여 클라이언트가 온라인 상태인지 확인할 수있는 유일한 방법은 패키지를 보내고 일정 시간 내에 응답하지 않으면 패키지를 목록에서 제거하는 것입니다.

+0

나중에 예외를 추가하여 충돌을 수정하려고했지만 어쨌든 계속 발생했습니다. –

+0

질문이 업데이트되었습니다. IDLE에서 초기 코드를 실행하여 추적 오류를 얻을 수있었습니다. 코드가 인쇄 줄에 나타나지 않는 것처럼 보이므로 제안이 작동하지 않습니다. 그것은 s처럼 보입니다.sendto()는 수동으로 프로그램을 닫고 except를 무시합니다. –

관련 문제