サーバとして動作する GTK アプリケーション

さきほどの Python でソケットGlib の g_io_add_watch の二点を組み合わせることで、ソケットから指示を受け付けるような GUI アプリケーションが実現できる。

以下のコードを実行後、telnet localhost 12345 によって接続して、ラベルの文字列を書き換えることができる。

import gtk, glib
import sys
import socket

class TestWindow:
    def __init__(self):
        self.window = gtk.Window()
        self.window.connect("destroy", gtk.main_quit)
        self.label = gtk.Label()
        self.label.set_label("received text will be shown here")
        self.window.add(self.label)
        self.window.show_all()
        
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(("127.0.0.1", 12345))
        self.sock.listen(1)
        glib.io_add_watch(self.sock, glib.IO_IN, self.listener)

    def listener(self, fd, condition):
        self.cli, addr = self.sock.accept()
        glib.io_add_watch(self.cli, glib.IO_IN, self.receiver)
        return True

    def receiver(self, fd, condition):
        msg = self.cli.recv(10)
        if msg == '':
            self.cli.close()
            return False
        msg = msg.rstrip()
        self.label.set_label(msg)
        return True

TestWindow()
gtk.main()

ポイントは、listen() によって接続を待っている socket に対するハンドラ(listener) と、accept() したコネクションからの入力を監視するためのハンドラ(receiver) の二つが必要だということだ。後者については、切断された場合にハンドラから False を返すことで、監視を解除している。