2012-06-10 2 views
2

여러 포트에서 수신 대기하는 non-blocking python udp 서버를 구현하려고합니다.non-blocking python udp 여러 포트 wierd 예외를 구현하는 시도

나는이 Stackover posting에 몇 가지 코드를 발견하여 여러 소켓에서 수신 대기하도록 수정했습니다.

내 코드는 다음과 같습니다. ,

/udp_non_blocking_listener.py 
[<socket._socketobject object at 0xb72804fc>, <socket._socketobject object at 0xb7280534>] 
Listening on port [7777, 7778] 
Connection from ('127.0.0.1', 41237) 
Traceback (most recent call last): 
    File "./udp_non_blocking_listener.py", line 27, in <module> 
    client_socket, address = s.accept() 
    File "/usr/lib/python2.7/socket.py", line 202, in accept 
    sock, addr = self._sock.accept() 
socket.error: [Errno 22] Invalid argument 

난 그냥 파이썬 비 차단 API에 시작 해요 :

#!/usr/bin/python 

import select 
import socket 

ports_list=[7777,7778] 


def make_socket(number): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    sock.bind(('', number)) 
    sock.listen(5) 
    return sock 


read_list= map(lambda x: make_socket(x), ports_list) 

print(read_list) 

print "Listening on port %s" % ports_list 

while True: 
    readable, writable, errored = select.select(read_list, [], []) 
    for s in readable: 
     if s in read_list: 
      client_socket, address = s.accept() 
      read_list.append(client_socket) 
      print "Connection from", address 
     else: 
      data = s.recv(1024) 
      if data: 
       s.send(data) 
      else: 
       s.close() 
       read_list.remove(s) 

나는 다른 콘솔

$ netcat localhost 7778 
dsa 

에서 netcat을 실행하여 테스트 그러나 그것은과 같이, borks 이런 일을하는 관용적 인 방법은 무엇입니까?

+0

이상한 솔루션 ... 당신은 오히려 스레드를 사용해야하며, 각각 하나 개의 소켓 전에서 수신한다 – ddzialak

답변

3

이미 수락 된 소켓이 일치하지 않습니다.

당신의 고정 코드 (notAccepted 소켓 소개 목록) :

#!/usr/bin/python 

import select 
import socket 

ports_list=[7777,7778] 


def make_socket(number): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    sock.bind(('', number)) 
    sock.listen(5) 
    return sock 


read_list= map(lambda x: make_socket(x), ports_list) 

print(read_list) 

print "Listening on port %s" % ports_list 

notAccepted = read_list[:] 

while True: 
    readable, writable, errored = select.select(read_list, [], []) 
    for s in readable: 
     if s in notAccepted: 
      client_socket, address = s.accept() 
      read_list.append(client_socket) 
      print "Connection from", address, client_socket 
     else: 
      data = s.recv(1024) 
      if data: 
       s.send(data) 
      else: 
       s.close() 
       read_list.remove(s) 
1

위의 파이썬 예제에 대해 아무것도 UDP있다. SOCK_STREAM은 TCP 용입니다.

0

마찬가지로 accept()입니다.

UDP의 경우 "연결"이 없으므로 accept()가 없습니다.

sendto() 및 recvfrom() 및 SOCK_DATAGRAM을 사용하십시오.

응용 프로그램이 페이로드에 적용 및/또는 포함 할 수있는 모든 상황을 제외하고는 하나의 UDP 데이터 그램과 동일한 호스트의 다음 프로토콜 간의 관계가 없습니다. 동일한 호스트 및 동일한 소스/dest addr/port tuple의 여러 데이터 그램이 동일한 클라이언트 응용 프로그램과 관련되어 있음을 보장하지 않습니다. 완전히 연결되어 있지 않으므로 모든 상태는 응용 프로그램과 페이로드의 내용에 의해 전적으로 관리되어야합니다.