2

複数のポートでリッスンするノンブロッキング python udp サーバーを実装しようとしています。

このStackover の投稿でいくつかのコードを見つけ、複数のソケットでリッスンするように変更しました。これまでのところ、とても良いです。

私のコードは次のとおりです。

#!/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を実行してテストします

$ netcat localhost 7778
dsa

しかし、それは次のように失敗します。

/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

私はPythonのノンブロッキングAPIを始めたばかりですが、このようなことをするための慣用的な方法は何ですか?

4

3 に答える 3

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)
于 2012-06-10T12:48:27.913 に答える
0

そのままaccept()。

UDP の場合、「接続」がないため、accept() はありません。

sendto() と recvfrom() と SOCK_DATAGRAM を使用します。

アプリケーションがペイロードに適用および/または埋め込む可能性のあるコンテキストを除いて、1 つの UDP データグラムと同じホストからの次のプロトコルとの間に関係はありません。同じホストからの複数のデータグラムと同じソース/宛先アドレス/ポート タプルが同じクライアント アプリケーションに関連付けられているという保証はありません。これは完全にコネクションレスであるため、すべての状態をアプリケーションとペイロードの内容によって完全に管理する必要があります。

于 2015-06-21T21:35:28.063 に答える