2012-05-15 2 views
1

저는 간단한 소켓 서버를 작성 중이며 클라이언트 상태 (인증 및 물건)를 추적하고자합니다. handle_read()가 호출 될 때마다 나는 그 특정 클라이언트에 대해 아무것도 모른다. 고객 ID 등을 알면 도움이 될 것입니다. 여기에 지금까지이 작업은 다음과 같습니다파이썬 asyncore는 클라이언트를 추적합니다.

import asyncore 
import socket 

class EchoHandler(asyncore.dispatcher_with_send): 

    def handle_read(self): 
     data = self.recv(8192) 
     self.send(data) 

class EchoServer(asyncore.dispatcher): 

    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is None: 
      pass 
     else: 
      sock, addr = pair 
      print 'Incoming connection from %s' % repr(addr) 
      handler = EchoHandler(sock) 

server = EchoServer('localhost', 8080) 
asyncore.loop() 

답변

4

repr(addr)에서 연결을받을 때 클라이언트의 ID를 알 수 있습니다. 반환 된 튜플은 해당 클라이언트에 데이터를 다시 보낼 때 사용할 수있는 해당 클라이언트의 IP 및 고유 번호입니다. 클라이언트 목록을 보관하려면 들어오는 연결을받을 때 해당 클라이언트의 정보를 저장하는 사전을 고려해야합니다.

class EchoHandler(asyncore.dispatcher_with_send): 
    def setAddr(self, addr): 
     self.addr = addr 

    def handle_read(self): 
     data = self.recv(8192) 
     print '%s from %s' % (data, self.addr) 
     self.send(data) 

class EchoServer(asyncore.dispatcher): 

    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.set_reuse_addr() 
     self.bind((host, port)) 
     self.listen(5) 

    def handle_accept(self): 
     pair = self.accept() 
     if pair is None: 
      pass 
     else: 
      sock, addr = pair 
      print 'Incoming connection from %s' % repr(addr) 
      handler = EchoHandler(sock) 
      handler.setAddr(addr) #Set the address of the sender in the EchoHandler 

단순히 EchoHandler에 클라이언트의 주소를 보내고, 지금 당신은에서오고 어디 있는지 알고 : 당신이 handle_read 기능에 전달 된 정보를 원한다면

, 코드는 다음과 같을 것이다. 희망/도움이!

+0

정확하게 필요한 것, 감사합니다! –

1

당신이 소켓에서 얻을 수있는 유일한 "ID가"직접 소켓과 보낸 사람의 주소에 대한 참조입니다. 다른 모든 것은받은 데이터를 기반으로합니다. 첫 번째 16 바이트로 ID를 보내면 그 이후의 데이터는 모두 데이터가됩니다. 즉, 요구 사항을 충족시키는 프로토콜을 효과적으로 구현해야합니다.

파이썬 표준 라이브러리에서 ssl과 같은 라이브러리를 사용하는 것이 쉽고 간편한 인증 방법입니다. ssl 라이브러리는 파이썬 소켓에서 쉽게 사용할 수있는 형태로 암호화 및 인증 메커니즘을 제공합니다. 보안 인증이 필요한 경우 기존 솔루션을 사용하는 것이 좋습니다.

+0

보낸 사람 주소로 충분합니다. handle_read() 함수에서 어떻게 얻을 수 있습니까? 자체 프로토콜을 구현하는 것은 기존 장치에서 작동해야하므로 문제가되지 않습니다. –

+0

@ Cryptite의 대답에서 말했듯이, 당신은'accept()'호출의 주소를'pair'의 seconf 부분으로 가지고 있습니다. 생성자를 생성하거나'EchoHandler'에 대한 별도의 설정 메소드를 생성하여 클래스에 저장함으로써'handle_read()'로 가져올 수 있습니다. – jhonkola

관련 문제