skkserv のプロトコルって解説してあるページがあんまりないのね。skkserv 自体についてはけっこう見つかるのに。
探してみると、ここに載ってた。
"0"
サーバへコネクションを切断するよう要求します。
"1eee "
「見出し」 eee に対する「変換文字列」を要求します。 " " (スペース)でターミネートされていることに注意が必要です。
サーバから返される「変換文字列」は / で区切られた "1/foo/bar/baz/\n" のような形式です。
サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。
「見出し」が存在しない場合は入力の先頭の "1" を "4" に変換したものをそのまま返します。 (実はプロトコル的には 4 で始まる文字列ならば何でも良いらしいですが、一部のクライアントで問題が出るとのことです。)
"2"
サーバへ「バージョンナンバー」を要求します。
サーバから返される「バージョンナンバー」は "A.B " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。
skkserv/skkserv.c に A はメジャーバージョン B はマイナーバージョンのような記述がありますが、skkserv 自体 "A.B.C " のような形式で返していますし、他のサーバではサーバ文字列を返しているものもあるので、バージョンナンバーというよりバージョン情報と表現すべきなのかもしれません。
"3"
サーバへ「サーバのホスト名と IP アドレスのリスト」を要求します。
サーバから返される「サーバのホスト名と IP アドレスのリスト」は "hostname:addr:[addr...:] " のような形式です。 " " (スペース)でターミネートされていることに注意が必要です。
yaskkserv では未実装です。(ダミー文字列が返されます。)
"4eee "
「見出し」 eee で始まる見出しを要求します。" " (スペース)でターミネートされていることに注意が必要です。
サーバから返される「見出し」は / で区切られた "1/foo/bar/baz/\n" のような形式です。
サーバから返される文字列の末尾には "\n" が必要なことに注意が必要です。
これは新しいプロトコルで、今のところきちんとした定義は無いようです。
だそうな。
手元の AquaSKK が skkserv サーバーにもなるので、それで試してみたところ、どうやら "4" には対応していないようだった。
というわけで早速書いてみた。
#!/opt/local/bin/ruby19 # -*- coding : utf-8 -*- require "socket" require "thread" port = 1178 s = TCPSocket.open("localhost", port) s.set_encoding("EUC-JP") req = nil t = Thread.new do l = "" s.each_char do |c| l << c if req == 1 && c == "\n" puts l.encode("UTF-8") puts "\n" l = "" elsif (req == 2 || req == 3) && c == " " puts l.encode("UTF-8") puts "\n" l = "" end end end s.write("2") req = 2 sleep 0.2 s.write("3") req = 3 sleep 0.2 s.write("1a ") req = 1 sleep 0.2 s.write("1あ ") req = 1 sleep 0.2 s.write("1ほ ") req = 1 sleep 0.2 s.write("0") req = 0 t.join s.close
結果
AquaSKKServer1.0 127.0.0.1:0.0.0.0: 1/α;alpha/エー/エイ/アー;(独語)/а;cyrillic/ア/ 1/亜/吾;私/彼;=吾/阿;阿呆/婀;婀娜っぽい/痾;宿痾/唖;聾唖/亞;「亜」の旧字(人名用漢字)/椏;また/娃;美女/哇/襾/安;?/明;?/嗚;?/ 1/帆/穂/補/歩/保/火;(古訓)火群/舗;店舗/鋪;≒舗/舖;「舗」の旧字/輔;輔佐/捕;逮捕/圃;圃場/堡;橋頭堡/葆/畝;うね/浦;うら/甫;杜甫/哺;哺乳/匍;匍匐前進/葡;葡萄酒/埔/脯;ほじし/餔;(くらう)/鯆;イルカ,サバ/黼;(縫取り)/蒲;蒲公英/逋;にげる/穗;「穂」の旧字(人名用漢字)/
IO#set_encoding に気づかなくて、Encoding.default_external を弄ったりしてたのがハマったところ。
なんで 2 & 3 と 1 で区切り文字が違うのかは不思議なところだが、普通に使うぶんには 2 や 3 は使わないので each_line で OK のはず。