2010年3月22日月曜日

RubyでUDPなServer/Clientを作ってみた

なにやらUDPを使ったアプリケーションを作成することになりそうなので、各クライアントから来た要求を全クライアントに返すサーバと、送信/受信を行うクライアントを作成してみた。

UDPなので、相手に届いているかを保証することはできない。
よって、このサーバ/クライアントでは「伝えること」より「リアルタイムで発信すること」を重視する。


まずはサーバ側を作成。

#!/usr/bin/env ruby
#-*- encoding: utf-8 -*-

require "socket"

SERVERIP = "192.168.0.105"
SERVERPORT = "62000"

clientList = Array.new

sock = UDPSocket.new
# サーバとして待ち受けるアドレスとポートを指定 
sock.bind(SERVERIP, SERVERPORT)

while true
# sockに出力が来るのを待つ
# 来なかったらnilを返す
sel = IO::select([sock])
if sel != nil
sel[0].each {|s|
# 最大65535byte分のデータを受け取る。
# データは配列として渡される。
# ["文字列", ["アドレス種別", 送信元ポート番号, "送信元ホスト名", "送信元IPアドレス"]]
# ["192.168.0.105 :43433 miku > miku\n", ["AF_INET", 62000, "192.168.0.105", "192.168.0.105"]]
data = s.recvfrom_nonblock(65535)
string = data[0].chomp!
ip, port = data[1][3].to_s, data[1][1].to_i
clientList << {"ip"=>ip, "port"=> port}
clientList.uniq!
# 各クライアントに向けて返信する
clientList.each{|client|
printf("Server > %-15s:%5d %s\n", client["ip"], client["port"], string)
# 実際に返信する。send("文字列", フラグ, "送信先IPアドレス", "送信先ポート")
sock.send(sprintf("%-15s:%5d %s\n", client["ip"], client["port"], string), 0, client["ip"], client["port"])
}
}
end
end

sock.close


次にクライアント側を作成する。

#!/usr/bin/env ruby
#-*- encoding: utf-8 -*-

require "socket"

if ARGV[0] == nil
puts "ex) ./client.rb miku"
exit 1
end

NAME = ARGV[0]
SERVERIP = "192.168.0.105"
SERVERPORT = "62000"

# UDPのソケットを作成
sock = UDPSocket.new
# バインドするIPアドレスとポートを自動で割り当てる
sock.bind("0.0.0.0", 0)


# サーバからの情報を受け取り表示するスレッドを作成
thread = Thread.new {
while true
# sockに出力が来るのを5秒待つ。
# 来なかったらnilを返す。
sel = IO::select([sock], nil, nil, 5)
if sel != nil
sel[0].each{|s|
data = s.recvfrom_nonblock(65535)
puts data[0].chomp!
}
end
end
}

# サーバに情報を送信するループ
while true
string = STDIN.gets.chomp!
sock.send(sprintf("%-5s> %s\n", NAME, string), 0, SERVERIP, SERVERPORT)
end

sock.close



実際に使用すると、このようになった。
UDPサーバ/クライアント実行結果


これだけで、簡単なチャットサーバ/クライアントが作成できた。
Cで書いたものを見たあとだと、Rubyが簡単過ぎて泣ける。

2010年3月8日月曜日

Debian(PPC)でLinux-VServerを使ってみる

Debianでのchroot環境について調べていたところ、chrootよりずっといい感じのLinux-VServerなるものが見つかったので、忘れないように書いておく。
感じとしては、FreeBSDのJailと似たようなもの…な気がする。

・aptitudeでvserver用のカーネルとツールをインストール。
# aptitude install linux-image-2.6-vserver-powerpc \
> util-vserver \
> vserver-debiantools


・vserver用カーネルで起動するため、再起動。
# reboot


・vserver用ファイルを準備。
vserver名をmikuとし、ホスト名をmiku.v.hachune.net、ディレクトリツリーの場所を/vsv/miku、ネットワークインターフェースにeth2を使用、1番のエイリアス(eth2:1)として10.39.39.100/24を割り当てる。ループバックにはlo:1を使用する。
"--"以降はdebootstrapのオプション。ここではDebian Lennyをftp.jaist.ac.jpから取得するように設定する。

# vserver miku build \
> --hostname miku.v.hachune.net \
> --rootdir=/vsv/miku --context 39 \
> --interface 1=eth2:10.39.39.100/24 --interface 1=lo:127.0.0.1/8\
> -m debootstrap -- -d lenny -m ftp://ftp.jaist.ac.jp/pub/Linux/Debian/


…これだけ。
後は、通常のDebian同様、起動して入ってサーバを設定する。
日本語を使用したい場合はaptitude install localesするといい。
・vserverを開始
# vserver miku start
・vserverを停止
# vserver miku stop
・vserverに入る
# vserver miku enter
・vserverの状態を確認
# vserver miku status
・vserverを削除
# vserver miku delete


詳しくはmanのvserver、verver-build、vserver-statあたりを参考にすると良いらしい。
一部デバイスの関係で正しく動作しないアプリケーションがあるようだが、chrootだけよりいい感じ。
基本システムのみなので、インストール直後の容量が252MBと、かなり小さめなのも嬉しい。
Mac Mini G4では、XenやVMwareが使えないしな…。

linux-vserver.org
http://linux-vserver.org/


※追記
動くものと動かないものは以下のとおり。

動作確認:
bind9
apache

動作せず:
OpenVPN: /dev/net/tunが無いため不可。
dhcp3-server: eth2:1を正しく認識しない…?


その他必要そうな設定
・TimeZoneの設定
# dpkg-reconfigure tzdata

・digが必要な場合
# aptitude install dnsutils

2010年3月5日金曜日

OpenBSDのカーネルを再構築

これまた忘れそうなので書いておく。


・適当なところからカーネルのソース等を持ってきておく。
今回は、以下の4つを取得。
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/src.tar.gz
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/sys.tar.gz
ftp://ftp.jaist.ac.jp/pub/openBSD/4.6/ports.tar.gz
ftp://ftp.jaist.ac.jp/pub/OpenBSD/4.6/xenocara.tar.gz


・ダウンロードしたファイルを展開する。
# cd /usr/src
# tar xzf /home/miku/sys.tar.gz
# tar xzf /home/miku/src.tar.gz
# cd /usr
# tar xzf /home/miku/xenocara.tar.gz
# tar xzf /home/miku/ports.tar.gz


・カーネルをビルド
# cd /usr/src/sys/arch/i386/conf/
# cp GENERIC.MP HACHUNE
→カーネル設定の編集はここで。
MPカーネル(マルチプロセッサ用のカーネル)の設定は、殆どがGENERICカーネルをincludeしたものなので、細かい設定はGENERICを編集して変更する。

# config HACHUNE
Don't forget to run "make depend"
# cd ../compile/HACHUNE
# make depend
# make
→ EeePC(Atom N270、DDR2-667 2GB、20GB IDE-USB HDD)だと、大体20〜30分位で終了。

・Buildしたカーネルをインストール(古いものをbsd.oldとしてとっておく)
# mv /bsd /bsd.old
# cp bsd /bsd

・再起動
# reboot
→もしコケたらブートローダーでbsd.oldを指定して起動


・ユーザーランドのビルド
# cd /usr/src
# make obj
# make build
→ カーネルのビルドよりずーーっと時間が掛かるのでゆっくり待つ。

・再起動
# reboot



…と、ここまでやっていたHDDがクラッシュ。
実験用HDDだからまぁ良いのだが、やっぱり凹むな…