2013-04-30 3 views
1

그래서 매우 간단한 에코 서버/클라이언트와 거래를하고 있습니다. 나는 결국 게임 서버를 만들 예정이지만, 지금은 기본 부분을 설정하려고합니다. 여기Python 소켓 라이브러리, Errno 10054 클라이언트가 종료 될 때

http://pastebin.com/qtfrMGur가 클라이언트의 : 여기

는 서버의 http://pastebin.com/3VK3VxPX

그래서, 내 문제는 클라이언트 연결을 끊습니다, 나는 socket.error 얻을 때이다 : [errno는 10054]를 기존 연결이 강제로 폐쇄되었다 원격 호스트 읽을 수있는 소켓 목록에 보류중인 정보가없는 경우 select.select()가 false (또는 빈 목록 등)를 반환한다는 인상을 받았습니다. 이것은 오류의 원인 인 것 같지만 클라이언트가 더 이상 존재하지 않으면 select.select()가 true를 반환하는 이유는 무엇입니까 (26 행)? 실제 오류는 27 번 줄에서 일부 정보를 가져 오려고 할 때 발생합니다. 소켓의 클라이언트 측이 닫혀 있다고 가정하면 정말 혼란 스럽습니다. []를 반환하지 말고 다른 곳으로 가야합니다. 31 번 라인에서 그 클라이언트를 파기 하시겠습니까?

게시 할 항목이 무엇인지 알지 못합니다. 매우 초보적인 문제인 것처럼 보입니다. 일반적으로 좀 더 추상적 인 라이브러리를 사용하여 쉽게 만들 수 있지만이 프로젝트에서는 전통적인 BSD 소켓을 사용해야합니다. 너희들은 다른 정보가 있으면 그냥 물어 봐야 해.

감사합니다.

편집 : 당신은 내가 적절한 종료 할 볼 수 있듯이

for cl in clients: 
     ready = select.select([cl], [], [], .1)[0] 
     print ready 
     if ready: 
      data = cl.recv(size) 
      if data: 
       print data 
       #cl.send(data) 
      else: 
       print "Client Quit\n" 
       clients.remove(cl) 
       cl.shutdown(socket.SHUT_RDWR) 
       cl.close() 
       print len(clients) 

: 그래서 [0]과 같이 select.select (...)의 값을 출력하기 위해 거기에 인쇄 문을 넣어 지금도. 문제는 바로 클라이언트가 종료 될 때 select.select (...)가 클라이언트 소켓을 읽을 수있는 소스로 반환하므로 cl.recv가 호출되어 다른 끝에서 cl이 닫혀 있기 때문에 오류가 발생한다는 것입니다 . 적어도 이것은 나의 의심이다.

그래서 누군가 내가 여기서 잘못하고있는 것을 설명해 주실 수 있습니까? 클라이언트가 마지막으로 죽어가는 메시지를 보내는 이유는 무엇입니까?

감사

EDIT2 : 그래서 너희들은 내 데비안 기계를 해고하고 코드는 그것이 이렇게 윈도우 만의, 완벽하게 작동합니다. 어떤 종류의 버그입니까? 소켓 라이브러리가 OS간에 인터페이스를 동일하게 만들기 위해 두포의 모든 내용을 추상화했다는 인상하에있었습니다.

+1

그냥 생각하지만 어쩌면 경쟁 조건입니다. 'recv'는 클라이언트를 반환 할 수 있고 클라이언트는 연결을 끊을 수 있습니다. 그래도 아주 운이 좋지 않은 것처럼 보입니다. – Felipe

+0

필자는 이것이 경쟁 조건이라고 생각하지 않습니다. 문제를 진단하기 위해 인쇄물을 몇 장 넣었고 select.select()가 클라이언트가 종료 될 때 클라이언트 소켓을 반환하고있는 것으로 보입니다.그것은 마치 클라이언트가 마지막 메시지 기능을 가지고있는 것처럼 보입니다. – robins35

답변

1

이 같은 클라이언트 측에서 그것을 닫기 전에, 소켓의 shutdown 메소드를 호출해야합니다

s.shutdown(socket.SHUT_RDWR) 
s.close() 

을가 송신/수신 더 허용하지 않습니다 그 방법에 대해 파이썬 문서를 체크 아웃 그것, 그것은 멋지게 거기에서 설명된다.

UPDATE : 고정 클라이언트 코드

import socket 

host = 'localhost' 
port = 50000 
size = 1024 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((host,port)) 

msg = '' 
while msg !='quit': 
     msg = raw_input() 
     s.send(msg) 
     #data = s.recv(size) 
s.shutdown(socket.SHUT_RDWR) 
s.close() 
+0

나는 여전히 클라이언트를 종료 할 때까지 Errno 10054를 던졌습니다. select.select ([cl], [], [], 0) [0] [0]의 결과를 인쇄했습니다. ,이 경우 클라이언트를 리턴합니다. 어떤 의미가 없나요? 클라이언트가 종료하고 닫을 때 cl.recv (크기)가 클라이언트를 반환하는 이유는 무엇입니까? – robins35

+0

ok이지만 클라이언트 쪽에서도 종료 메서드를 호출해야합니다. 실제로는 클라이언트 쪽에서 만 호출해도 오류는 발생하지 않지만 양쪽에서 호출하는 것이 가장 좋습니다. 내 대답을 고정 된 클라이언트 코드로 업데이트하십시오. – andrean

+0

나는 둘 다 부르고있다. 클라이언트가 연결이 끊어 졌음을 감지하는 쉬운 방법이있는 경우. – robins35