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だからまぁ良いのだが、やっぱり凹むな…

2010年2月28日日曜日

DebianでNFSサーバ&クライアント

ググれば大量に出てくるものを書いてもなんかなぁ...と思いつつも、
そんなことを考えていると全然Blogが書けないということに気がついたので、もう遠慮なく書くことにする。

今回は、かがみねサーバ(kagamine.h.hachune.net)の/home/mikuをめぐりねサーバ(megurine.h.hachune.net)の/home/mikuにマウントする。

まず、かがみねサーバ(NFS Server)の設定。
% sudo aptitude install nfs-kernel-server
% sudo vi /etc/exports
で、以下を追加する。
/home/miku *.h.hachune.net(ro,sync,no_subtree_check)


・ディレクトリをエクスポート(再エクスポート)する。
% sudo exportfs -ar
(nfs-kernel-serverを再起動する方法もある)

・公開できているか確認する。
% showmount -e


次に、めぐりねサーバ(NFS Client)の設定を行う。
/etc/fstabに以下を追加し、sudo mount -aする。
kagamine.h.hachune.net:/home/miku /home/miku nfs ro,sync 0 0

これでマウントできた。
サーバ側でshowmount -aコマンドを打つと、マウント状況が確認できる。
簡単だけれど、セキュアではないな…


/etc/exportsの書式は、man exports、
/etc/fstabのNFS関連の情報は、man nfs、
NFSエクスポートリスト操作コマンドexportfsの情報は、man exportfs
マウント情報確認コマンドshowmountの情報は、man showmount
を見ると良い。

Ruby1.9.1のcursesでUTF-8文字列を表示

RubyのCursesでプレイリスト操作ツールを作成しようとしたところ、文字化けして全然使い物にならないということが判明。ついでなので1.9.1にパッチを当ててビルドしてみることにする。

・ext/curses/curses.cを編集

追加:
+ #include "locale.h"

Init_curses関数内にsetlocaleを追加:
Init_curses()
{
+ setlocale(LC_ALL, "");


・ext/curses/extconf.rbを編集(ncurseswを探すようにする)

削除:
-if have_header(*curses=%w"ncurses.h") and have_library("ncurses", "initscr")
追加:
+if have_header(*curses=%w"ncurses.h") and
+ ( have_library("ncursesw", "initscr") or have_library("ncurses", "initscr") )
+ make=true
削除:
-elsif have_header(*curses=%w"ncurses/curses.h") and have_library("ncurses", "initscr")
追加:
+elsif have_header(*curses=%w"ncurses/curses.h") and
+ ( have_library("ncursesw", "initscr") or have_library("ncurses", "initscr") )
+ make=true


・ruby-1.9.1-p378.tar.bz2をダウンロード
・ libncursesw-devをaptからインストール
% sudo aptitude install libncursesw-dev

・ビルド。-O2だと何故か途中でコケるらしいので、-O3にする。
% optflags="-O3 -pipe" ./configure --prefix=/usr/ruby19 --program-suffix=19

2010年2月19日金曜日

現状

なんか色々忘れそうなので書いておく。

ゼミ用論文…texA450枚越え。卒論として提出する時には一体どうなっていることやら…
応用情報技術者…毎日ちょっとずつ勉強。
Ruby…最近あんまり大きいのは作っていない。mtmef v2.0をさっさとどうにかしたい。Winでしか動かないのは不便過ぎる。
C…細かいのをいろいろやってる。
Python…あんまり触れてない。ついRubyに行ってしまう…

# はちゅね転送サービスの影響でAjaxが気になりだした。
# ちょっとやってみたら意外といけそうな気がした(ブラウザを気にしなければw)。
# 作業の効率化の為にも、zshをどうにかしたい。


鯖…最近環境を一期に更新中。去年作ったkagamine-server(Debian 5)大活躍。
逆にhatsune-server(WS2008R2)がちょっと弄れていない状態。
hatsuneは音楽関連専用機になりつつあるな…

megurine-serverは今年に入ってからほぼ常に稼働中。
春休み中にmegurine一度全部見直したいが、どうだろう。

hachune.net用Webサーバのバックアップもほぼ準備完了。
後は改良し続けるだけ…な気がする。
セキュリティの向上も必須。Gumblarとかにはまず引っかからないだろうけど。
公開サーバでパスワード認証とか怖すぎてもうできないw

# ルータがちょっと危険…かも?(VPN的な意味で)
# そろそろルータぐらい自作すべき(OpenBSDあたりでw)


まだ卒業まで1年ある。その間はひたすらこんな感じで勉強。
それでも、終わるのが早すぎて泣ける。

2010年2月14日日曜日

はちゅね転送サービス 開始!

以前勢いで取得したhachune.netドメインを使用し、URL転送サービスを作ってみた。

例えば、
otomania.hachune.netにアクセスが来たら、Otomaniaさんのページhttp://www.otomania.netに転送する
pocopoco.hachune.netにアクセスが来たら、たまごさんのページhttp://www.pocopoco.ccに転送する
twitter.hachune.netにアクセスが来たら、私のTwitterページhttps://twitter.com/Phenomerに転送する
といったことができます。

「サーバを間借りして作ったサイトに、分かりやすい名前が欲しい!」
「自分のボカロなサイト・ブログに分かりやすい別名を付けたい!」
などといった時に使えるかと思います。


詳細は以下からどうぞ。
http://hachune.net/hachune-forward.html


.comがドメイン広告になってるな…なんか寂しい。