select は偉大だけど使いづらい。

もっとシンプルに書けないものだろうか。
とりあえず投げたら返してくれます。
telnet localhost 12345 とかやって接続すれば繋がります。
ターミナルを二つ起動して適当にメッセージを送ってみてくださいまし。

あとはHIGE(id:soundkitchen)がなんか作ってくれるの待つだけか。

select_echo_server.py

# vim: fileencoding=utf8 sw=4 sts=4

import socket
import select

class BroadcastEchoServer(object):
    """
    $ telnet localhost 12345
    """
    def __init__(self, port):
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind(('', self.port))
        self.server_socket.listen(5)

        self.descriptors = [self.server_socket]
        print 'EchoServer started on port %s' % self.port

    def run(self):
        while True:
            r, w, e = select.select(self.descriptors, [], [])
            for sock in r:
                if sock == self.server_socket:
                    self.accept_new_connection()
                else:
                    data = sock.recv(8192)

                    if data == '':
                        sock.close()
                        self.descriptors.remove(sock)
                    else:
                        self.broadcast_string(data, sock)

    def accept_new_connection(self):
        new_socket, (remote_host, remote_remport) = self.server_socket.accept()
        self.descriptors.append(new_socket)

    def broadcast_string(self, data, omit_socket):
        for sock in self.descriptors:
            if sock != self.server_socket and sock != omit_socket:
                sock.send(data)

        host, port = omit_socket.getpeername()
        print '[%s:%s] %s' % (host, port, data),

if __name__ == '__main__':
    server = BroadcastEchoServer(12345).run()

ほぼぱくらせていただいた文献

Sockets Programming with python
http://www.scribd.com/doc/134861/Sockets-Programming-with-python