2009年11月28日土曜日

boost::asio udp 考察

 boost::asio の udp について、少しコツがわかったので、ポストします。ごちゃごちゃと説明するよりは、コードを見てもらった方がはやいと思うので、いきなりコードです。

// ping_pong_server.cpp

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <iostream>

using boost::asio::ip::udp;

//
// サーバ側から見た、通信の流れ
// 実装は、bind の順序が下図どおりではない点に注意
//
// CLIENT SERVER
// bind_accept
// ---- connect ----> => handle_accept
// bind_ack
// <---- ack -----
// => handle_ack
// bind_receive
// ---- data 1 ----> => handle_receive
// bind_ack
// <---- ack -----
// => handle_ack
// bind_receive
// ---- data 2 ----> => handle_receive
// bind_ack
// <---- ack -----
// => handle_ack
// bind_receive
// ---- data 3 ----> => handle_receive
// bind_ack
// <---- ack -----
// => handle_ack
// bind_receive
// ---- data 4 ----> => handle_receive
// bind_response
// <--- data 1+2+3+4 ---
// => handle_response
//
// Async 実装上のコツは、キャッチャーミットを構えておいて
// ボールを投げる。この一点につきるかもしれない。

class ping_pong_server {
private:
boost::asio::io_service io_service_;
udp::socket socket_;
udp::endpoint client_endpoint_;
std::string ball_;
int count_;
boost::array<char,512> buffer_;
boost::array<char,1> ack_buffer_;

private:
void bind_accept() {
//std::cout << "bind_accept" << std::endl;
socket_.async_receive_from(
boost::asio::buffer( buffer_ ),
client_endpoint_,
boost::bind(
&ping_pong_server::handle_accept, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_accept(
const boost::system::error_code& error,
size_t bytes_recvd
) {
//std::cout << "handle_accept" << std::endl;
if( !error ) {
ball_.append( &buffer_[0], bytes_recvd );
std::cout << "*:" << client_endpoint_.port() << ":" << ball_ << std::endl;
++count_;
// ACK を送信する前に、受信の準備をしておく事が重要
bind_receive();
// 受信の準備なしに ACK を送信すると、受信が間に合わなくなる可能性がある。
bind_ack();
} else if( error != boost::asio::error::operation_aborted ) {
std::cout << error.message() << std::endl;
start();
}
}
void bind_ack() {
//std::cout << "bind_ack" << std::endl;
socket_.async_send_to(
boost::asio::buffer( ack_buffer_ ),
client_endpoint_,
boost::bind(
&ping_pong_server::handle_ack, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_ack(
const boost::system::error_code& error,
size_t bytes_transferred
) {
// ACK の送信が完了した段階で、受信するコードを書く事ができるが、
// ここで bind_receive するのでは、タイミングが遅い可能性がある。
//std::cout << "handle_ack" << std::endl;
}
void bind_receive() {
//std::cout << "bind_receive" << std::endl;
socket_.async_receive(
boost::asio::buffer( buffer_ ),
boost::bind(
&ping_pong_server::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_receive(
const boost::system::error_code& error,
size_t bytes_recvd
) {
//std::cout << "handle_receive" << std::endl;
if( !error ) {
ball_.append( &buffer_[0], bytes_recvd );
std::cout << client_endpoint_.port() << ":" << ball_ << std::endl;
++count_;
if( count_ < 4 ) {
// ACK を送信する前に、受信の準備をしておく事が重要
bind_receive();
// 受信の準備なしに ACK を送信すると、受信が間に合わなくなる可能性がある。
bind_ack();
} else {
// cleint_endpoint_ が更新されないうちに最後のレスポンスを送信
bind_response();
// 次の受信サイクルを開始する
start();
}
} else if( error != boost::asio::error::operation_aborted ) {
std::cout << error.message() << std::endl;
start();
}
}
void bind_response() {
//std::cout << "bind_response" << std::endl;
socket_.async_send_to(
boost::asio::buffer( ball_ ),
client_endpoint_,
boost::bind(
&ping_pong_server::handle_response, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_response(
const boost::system::error_code& error,
size_t bytes_transferred
) {
// ここでも先手を打ってあるので、何もしない
//std::cout << "handle_response" << std::endl;
}

void start() {
ball_.clear();
count_ = 0;
bind_accept();
}

public:
ping_pong_server()
: io_service_()
//, socket_(io_service_,udp::endpoint(udp::v6(),8080))
, socket_(io_service_,udp::endpoint(udp::v4(),8080))
, client_endpoint_()
, ball_()
, count_()
{
}

void run() {
start();
io_service_.run();
}


};

int main() {
ping_pong_server pps;
pps.run();
return 0;
}


これに対して、クライアント側のコードです。


// ppclient.cpp

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <string>
#include <iostream>

using boost::asio::ip::udp;

const char *msgs[] = { "ping", "pong", "pang", "pong" };

class ping_pong_client {
private:
boost::asio::io_service& io_service_;
udp::resolver resolver_;
udp::socket socket_;
udp::endpoint server_endpoint_;
int count_;
boost::array<char,512> buffer_;
std::string result_;

private:
void bind_send() {
//std::cout << "bind_send(" << msgs[count_] << ")" << std::endl;
socket_.async_send(
boost::asio::buffer( msgs[count_++], 4 ),
boost::bind(
&ping_pong_client::handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_send(
const boost::system::error_code& error,
size_t bytes_transferred
) {
//std::cout << "handle_send" << std::endl;
if( error ) {
std::cout << error.message() << std::endl;
}
}

void bind_ack() {
//std::cout << "bind_ack" << std::endl;
socket_.async_receive_from(
boost::asio::buffer( buffer_ ),
server_endpoint_,
boost::bind(
&ping_pong_client::handle_ack, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_ack(
const boost::system::error_code& error,
size_t bytes_transferred
) {
//std::cout << "handle_ack(" << count_ << ")" << std::endl;
if( !error ) {
if( count_ < 3 ) bind_ack();
else bind_receive();
bind_send();
} else {
std::cout << error.message() << std::endl;
}
}
void bind_receive() {
//std::cout << "bind_receive" << std::endl;
socket_.async_receive_from(
boost::asio::buffer( buffer_ ),
server_endpoint_,
boost::bind(
&ping_pong_client::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void handle_receive(
const boost::system::error_code& error,
size_t bytes_recvd
) {
//std::cout << "handle_receive" << std::endl;
if( !error ) {
result_.assign( &buffer_[0], bytes_recvd );
} else {
std::cout << error.message() << std::endl;
}
}
void start( const char* host, const char* port ) {
//std::cout << "start(" << host << "," << port << ")" << std::endl;
udp::resolver::query query(host, port);
resolver_.async_resolve(
query,
boost::bind(
&ping_pong_client::handle_resolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::iterator
)
);
}

void bind_connect(
udp::resolver::iterator endpoint_iterator
) {
//std::cout << "bind_connect" << std::endl;
server_endpoint_ = *endpoint_iterator;
//std::cout << server_endpoint_ << std::endl;
socket_.async_connect(
server_endpoint_,
boost::bind(
&ping_pong_client::handle_connect, this,
boost::asio::placeholders::error,
++endpoint_iterator
)
);
}

void handle_resolve(
const boost::system::error_code& error,
udp::resolver::iterator endpoint_iterator
) {
//std::cout << "handle_resolve" << std::endl;
if( error ) return;
bind_connect( endpoint_iterator );
}

void handle_connect(
const boost::system::error_code& error,
udp::resolver::iterator endpoint_iterator
) {
//std::cout << "handle_connect" << std::endl;
if( !error ) {
bind_ack();
bind_send();
} else if( endpoint_iterator != udp::resolver::iterator() ) {
bind_connect( ++endpoint_iterator );
} else {
std::cout << error.message() << std::endl;
}
}

public:
ping_pong_client(boost::asio::io_service& io_service)
: io_service_(io_service)
, resolver_(io_service_)
, socket_(io_service_)
, count_()
{
}

std::string run( const char* host, const char* port ) {
count_ = 0;
start( host, port );
io_service_.run();
return result_;
}

};

boost::asio::io_service io_service;

int main() {

ping_pong_client ppc( io_service );

std::cout << ppc.run("localhost","8080") << std::endl;

return 0;
}



 と、まぁ、1対1の通信ならば、これで、うまく行きます。では、同時に多対1の通信にするとどうでしょうか?というテストコードが以下です。


// 前半は同じ。

boost::asio::io_service io_service;
boost::array<std::string,10> slot;
boost::array<boost::thread,10> thr;

void tfunc( int i ) {
ping_pong_client ppc( io_service );
slot[i] = ppc.run( "localhost", "8080" );
}

int main() {
boost::thread_group threads;
for( int i = 0; i < 10; ++i ) {
thr[i] = boost::thread( &tfunc, i );
threads.add_thread( &thr[i] );
}
threads.join_all();
for( int i = 0; i < 10; ++i ) {
std::cout << slot[i] << std::endl;
}
return 0;
}


 これで実験してみたところ、async_receive_from と async_recieve も変わりなく、ごちゃ混ぜになりました。UDP は、コネクション・レスという事で、1Query 1Response のタイプのものが多いです。このような状況で、セッションという概念を持ち込むのは、かなりしんどそうです。このサンプルのように、通信をする場合は、トラスティッド・ネットワークで1対1が保障されるような場合にしか使えないという事のようです。

2009/12/01 追記、どのみちマルチ版は、まともに動作しないのですが(通信がちゃんと終了しないため)、boost::asio を使ったマルチスレッドのサンプルとしては、でたらめなので、後でフォローしなおします。

2009年11月25日水曜日

いろいろ

 左鎖骨遠端部骨折ですが、3つに分解したところの端が、くっつき始めました。で、現在は、徐々にくっついてきていて、中途半端にゴキゴキする感じが気持ち悪いです。

 仕事の方は、やる事が多すぎて、首がまわりません。まぁ、あちこち放置プレー。手がかかる事が多いというのは、まだまだ能力不足なんでしょうか?それとも器用貧乏なんでしょうか…。

 息子のスキーを揃えました。昨年まで、ソリにすら興味を示さなかったのに、大丈夫なのか一抹の不安があります。

 boost::asio の udp のコツが、なんとなくわかった気がするので、暇を見てサンプルを書いて、ポストする予定。こう書いて、宣言しとかないと、立ち消えになりそう…。

 仮面ライダー・カブトと響鬼を、わりとまじめに見ました。新ライダーのシリーズって、結構おもしろいかも?カブトは、水島ヒロが主人公なんで、嫁さんにも好評でした。ちなみに、うちの坊ちゃんに「少年」って、呼びかけたら、「少年じゃない!」って怒られました(´・ω・`)

Android と Chrome OS

 もし、Android と Chrome OS が統合されるのであれば、恐らく、Android も地に落ちるだろう。強制されるクラウドなんて、まっぴら御免だ。ストールマン氏の言うように、自己管理権だけは譲れない。選択肢の無い自由に何のメリットがあろうか?これが本当ならば、Android は、モバイル戦争から脱落だな。

2009年11月23日月曜日

asioのudp

 うーん…。udp で組み直してるけど、udp socket の async_receive, async_send が、どうにも思うように動作してくれない…。しかも、free function の async_read も udp の socket には対応していないみたいで、エラーになってしまった。
 そんな訳で、N2175 を印刷して、まじめにチェックする事に…。

 udp の場合

   async_receive_from 任意のクライアントから受信する
   async_receive 一旦受信して endpoint の確定したクライアントから受信する
   async_send_to 送信先を指定して送信する
   async_send 一旦送信して endpoint の確定した所へ送信する

という理解が間違っているのか…? async_receive_from と async_send_to は、ちゃんと動作するんだけどなぁ?udp って、セッションレスなんでしょうか? packet の構造調べてみたけど、セッションレスには思えないっす…。うーむ…。

2009/11/24 追記: どうやら、udp の場合 tcp と違って、ack を返さないので、通信のタイミングがシビアなようである。当たり前と言ってしまえば、それまでの事ですが…  間に std::cout << "hoge" << std::endl というようなコードを挟んでやると、通信できるようになったりしました。

2009年11月19日木曜日

IE9

まぁ、みんな気になっているのが、いつになったら標準をインプリメントしてくれるのか?だ。特にHTML5なんかよりも、Canvasのサポートは、どうしたーーーー。
あーーー?
 Canvasのサポートは、どうしたーーーーーーーーーーーーーーーーー
 あーーーーーーーーん???
  Canvasのサポートは、どうしたーーーーーーーーーー。
   はぁぁぁぁぁあ?標準をインプリメントしろよーーー。

ふざけんな!!!標準をサポートしなさい!!!でしょう。
コメントを見ても、怒号の嵐だった。標準をインプリメントしてくれないから、みんな、涙を流すような美しいコードを書いているのです。自覚しろよ。つか神経無いのか?

2009年11月18日水曜日

やっと Windows7 へ移行した

 アップグレードに時間がかかる事は知っていたが、いやはや、ほんとに時間がかかった。

 GoogleToolbar が削除されていないという苛めには、レジストリで「GoogleToolbar」を検索して、片っ端からエントリを削除する事で対応した。普通のユーザにはお勧めできない方法だ。CLASS-ID 丸ごと削除とか、怖くてできないと思う。Extras うんぬんの苛めは、警告程度でしかなかったのかもしれない。Ticker とか、Extras に含まれる更新も全てアンインストールしておいた。

 非生産的OSであるVistaと違って、軽快に動作するので気持ちが良い。コントロール・パネルの動きなんか100倍ぐらい速くなったのではないだろうか?

追記: Norton UAC Tool を非互換でリストアップしとけよ。何事かと思ったぞ!

Windows7 買ってきた

 史上最も非生産的OSであるWindows Vistaに嫌気がさして、Windows7を買ってきた。Vista 何かしようと思うと数分間だんまりを決めこんで、反応がなくなるし、眠らない(シャットダウンしない)し、手がかかる。このOSのせいで、ロスした時間を考えると、計り知れないものがある。で、アップデートをした方が時間の節約になるだろうと踏んでいたのだが、甘かった。

 現在、
  • 削除されているはずの GoogleToolbar がインストールされている
  • Vista Ultimate Extras の言語パックがインストールされている(入れてないってば)
という理由で、アップグレードできないという苛めにあっている。

 コンポーネントの追加と削除から、Extras のチェックを外したら、何時間たっても反応がないので、OS付属のインストーラ・アプリケーションを強制終了させて、再度確認したらチェックが外れていた。しかし、更新プログラムの履歴を見ると、Extras のサービスパックがインストールされていて、こいつをアンインストールしようとするが、ひとつをアンインストールするのに1時間近くかかる。

 これならば、クリーン・インストールをしてデータを移行した方が、なんぼか早くね???

 という訳で、史上最悪のマイクロソフト製品は

  • 第一位 Microsoft Access 1.0
  • 第二位 Microsoft Windows Vista

です。

2009年11月14日土曜日

産学官連携の削減について

 産学官連携の予算を無くす事について、思うところを述べたい。

 先日、ワールド・ビジネス・サテライトで、京都大学が特許技術を米国へ売り込むという特集ニュースを見た。これ自体に異論があるわけではない。世界はフラット化しており、日本だけで何とかしようという時代は終わっているのかもしれないからだ。

 ところが、情報化時代の傾向として、Winner takes all. がある。この事により、投資格差は広がるばかりであると感じる。特にベンチャー投資という土壌の育たない日本では、これは問題ではなかろうか?事業仕分け委員会の言うように、学だけを強化すると、この時代だから日本政府が投資したお金は、他国の企業を強化し、益々格差を広げるための頭脳として使われる事になるのではないか?こういった懸念をぬぐえない。

 地方都市では風当たりが強くても、風の正体がよくわかっていないところがある。刺激の多い都市と比べて、啓蒙活動が必要なのである。それなしでは、地方の経済は低下し、老人だけが取り残され、疲弊し、人口減少に拍車がかかる。

 大学が独立行政法人化されてから、大学も変わったな?と感じている。大学の先生が主導して積極的に産学連携を模索するなど、気概を感じているのだ。

 大して効果の無い無駄な事業を支援しろとは言わない。だけど、投資どころを間違えないで欲しい。

 北海道では、コンサドーレのお金の使い方
  • 有力選手にお金を払わないで、J1リーグを陥落
  • J2リークで人気が無いから、札幌ドームで試合を開催できない(開催できていれば、試合で投資を上回る資金が回収できたと考えられる)
  • 実力の無い有名監督に、有力選手に払っていれば…という無駄な投資を決行

を間近にしたり、
 
 HARP構想というSaaS基盤をSaaSが定着する前にぶちあげて、それを推進できる人材がいたにもかかわらず、「何もするな」と投資を怠り、チャンスを逸してしまった事例を間近にしてきた。

 くれぐれも、投資どころは考えて欲しい。今のやり方に問題があるなら、違うやり方でもいいではないか?それこそ、望むところである。

技術立国日本?茶茶茶

 痛いニュースのスパコン発言とか見て思った事。

 まず、民主党のやっている「仕分け作業」とやらは、大いにやって欲しい。今まで、こういった評価自体が皆無で、投げっぱなしジャーマンだったのだから、しょうがない。しかし、仕分け作業等で評価された事が全て正しいとは限らない。間違いは正せばよいだけの話。


 私がブログを始めるにあたって一番伝えたかった事にもあるように、情報戦の時代に突入しているのである。そんな時代にあって、スパコン1位が重要か?だと???どたまかち割ったろかーーーぼけーーーー。今日の新聞を読んでみろ。業績が好調な企業はインターネットの絡んだ企業ばかりだし、ANAが航空券の販売手数料を引き下げ、理由は8割がネットで購入しているから…だ。この時代は、Winner takes all. ですよ。頭を使わないで、どうやって生き残っていくつもりなの???

追伸:

 亀井大臣のメンバーに外人が含まれる発言には呆れる。批判のベクトルが的外れ。

2009/11/18 追記:
 1位を目指して結果として1位じゃなかったら?って話だったとは…。1位を目指す気概が重要だけど、そこは競争なので、1位でなくても仕方が無い。そもそも時間当たりの単純な並列計算量は、競ってもしょうがないです。そこを比較されてもなぁー。あくまで、並列では厳しいというか、難しい計算に価値があるのです。というプレゼンをちゃんとしないと…。
 

13日の金曜日

 ネタもと

 誰か、もうちょっとスマートなのキボンヌ


#include <boost/date_time/gregorian/gregorian.hpp>
#include <iostream>

int main() {
using namespace boost::gregorian;
date today = day_clock::local_day();
date sday( today.year(), today.month(), 13 );
month_iterator miter( sday );
int loop = 520;
do {
if( (*miter).day_of_week() == Friday ) std::cout << *miter << std::endl;
++miter;
} while( --loop );

return 0;
}

2009年11月13日金曜日

個人情報とサービス

 一ヶ月以上前にPマークの個人情報管理責任者向けセミナーに参加しました。その時の牧野二郎先生のセミナーが面白かったです。内容は、インターネットのクッキーを利用する事により、超個人情報を活用した動的ページの作成が海外では標準となっている。という感じのものでした。

  1. パソコン2台持っているならば、1台はクッキーを有効にし、別の1台はクッキーを無効にし、しばらく利用してみてください。
  2. この状態で、2台同時に同じ内容で検索を実行してみてください。
  3. さあ?画面に表示されている内容は、同じですか?


を実践してみれば実感できますよ。というものでした。

 現在、クッキーの位置づけとしては、個人の名前は無いけれども個人と結びついた一意のIDによる何らかの情報が入ったものである。よって、グレーゾーンながら個人情報とは違う。という見解が一般的だと思います。ところが、この中に何を行ったか(具体的には、買い物をした閲覧した履歴など)が、記録されており、これら情報も大量に集積すれば、個人が特定できてしまうという問題があります。考えてみれば、世界に1つしかないものを購入すれば、それを購入したという履歴1つで、個人が特定できてしまうのです。こういう問題についても、これからは考えていきましょうよ!そして、考えた上で積極的に利用しましょうよ!という講演内容でした。

 ここから先は、セミナーから逸脱した私個人の見解です。

 情報リテラシーに書いたように、サービスを享受するにはトレードオフが存在します。例で挙げたのはアマゾンのアフィリエイトでしたが、GMail や Blogger や Google Reader などなど、これらの無料サービスから収集された個人の趣向を利用して、効果的な広告を出す事だって、トレードオフだと言えます。ターゲット広告は、クッキーだけが対象ではありません。

 もっと嫌な言い方をすれば、Google Analytics, 様々な便利な Google API, これらを利用して個人の行動履歴が収集され、利用されている可能性が十分にあるって事なのです。Google のサービスを享受しており、Google アカウントのログイン状態クッキーを利用していれば可能でしょう。ウェブ履歴の収集は余計なお世話と言いたいです。

 Google の強みは、BigTableにより情報が一ヶ所に集約されているところです。個々のサービスが独立していて、設定した内容が他のサービスに反映されなかった Livedoor とは、一味違います。最近、Google が、グーグル・ダッシュボードを発表し、なるほど、Googleは悪ではないのかな?とも思います。しかし、どこまで公開されているのか一抹の不安はあります。

2009年11月10日火曜日

TIME_WAIT にやられた

WAN で連帯するシステムで、動的IPって何だよ!の続きです。
 まぁ、最初の話では、当然固定IPで、サーバOSを入れるに決まってんだろーという話をしていたんです。それが、どこをどう転がれば、動的IPとWinXPにDBサーバとGISのサーバをぶっこんで、そのマシンでクライアント・アプリも動かして、IISが稼働してSoapのISAPIからGISサーバやDBサーバに更新かけて、ペンティアム4のシングル・コア、メモリ2Gで動いてます…って話になるんだよ!という構成のシステムがあってですね。
 負荷をかけると、途中で外部センターからのデータ送信が失敗するという現象が起こる…ってんで、現調してました。どうも、そのマシン内でのTCP接続が途中で失敗しているのが原因みたいでした。ISAPI の DLL から、TCP接続をかけていて、TCPのクライアント側からちゃんと切断しているけども、netstat -a で見ると TIME_WAIT の嵐!
 センターから IIS への Soap 通信は、HTTP/1.1 の接続で、Keep-Alive が効いているので、一度に大量の更新をかけても基本的に接続数が増えない。しかし、Soap の1リクエスト毎に TCP 接続しているので、こちらの後処理がうまく行っていなければ問題である。IIS への Soap 通信も細切れになる可能性は十分にある。自前で書いてる部分は、TIME_WAIT でも SO_REUSEADDR オプションを指定して回避は可能であるけども、IIS 等はアウト・オブ・アンダーコントロールである。TIME_WAIT に絡む設定を調べていくうちに、WinXP では、ポートの最大接続数は 5000で、切断までの最大待ち時間は 120 秒で、サーバ用途では少なくとも、5000, 60秒という設定になるらしい事が判明した。負荷も考えると短時間に大量に接続と切断が繰り返されるのであれば、20000, 30秒ぐらいでも良いと思う。
 参考1参考2
 ちなみに、boost::asio で、コントロールしようと思うと、こんな感じになるのでしょうか…。

 納得が行かないのは、自前で書いたTCPの切断…。CLOSE_WAIT や TIME_WAIT とかが気持ち悪いので、クライアントから切断するようにしたのに、ゴミが残る???見ると、ウィルス・チェッカーがパケットをスニッフしていて同じように TIME_WAIT をしてる…。うーん…クライアントから切断時に FIN が飛んでないのか?ウィルス・チェッカーが行儀悪いのか?何か別の原因か?

 とりあえず、ISAPI.DLL からは、どうせ同一マシン内の接続しか無いようなので、スピード・アップと TIME_WAIT 対策も兼ねて UDP で接続する事にし、レジストリのパラメータを

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort = 20000
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay = 30

という風にする事で回避する事にした。

2009/11/11 追記: TIME_WAIT は迷子になったパケットが到着するための受け口として存在するようです。よって、正規の動作と考えて良いみたいです。ちなみに非同期IOでコントロールしていれば、迷子もクソも無さそうに思えます。

2009年11月8日日曜日

boost::polygon

 キターッ!!!という気がするのだけども、とりあえず演算してみることに…。やっつけスクラッチです。


//#pragma warning (disable: 4351)
//#pragma warning (disable: 4805)

/*
Copyright 2008 Intel Corporation

Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
*/

#include <boost/polygon/polygon.hpp>
#include <boost/foreach.hpp>
#include <cassert>
#include <iostream>
namespace gtl = boost::polygon;
using namespace boost::polygon::operators;

typedef gtl::polygon_data<int> Polygon;
typedef gtl::polygon_traits<Polygon>::point_type Point;
typedef std::vector<Polygon> PolygonSet;

std::ostream& operator << (std::ostream& os, const Point& p ) {
os << "(" << x(p) << "," << y(p) << ")";
return os;
}

std::ostream& operator << (std::ostream& os, const Polygon& p) {
Polygon::iterator_type s = p.begin();
Polygon::iterator_type e = p.end();
while( s != e ) {
os << *s << ",";
++s;
}
return os;
}
std::ostream& operator << (std::ostream& os, const PolygonSet& s) {
BOOST_FOREACH( const Polygon& p, s ) {
os << p << " : ";
}
return os;
}


int main() {

Point pts1[] = {
gtl::construct<Point>( 0, 5000),
gtl::construct<Point>( -4330, -2500),
gtl::construct<Point>( 4330, -2500)
};
Point pts2[] = {
gtl::construct<Point>( 0, -5000),
gtl::construct<Point>( 4330, 2500),
gtl::construct<Point>( -4330, 2500)
};


Polygon poly1, poly2, poly3, poly4;
gtl::set_points(poly1, pts1, pts1+3);
gtl::set_points(poly2, pts2, pts2+3);

PolygonSet ps1, ps2, ps3, ps4, ps5;
ps1 += poly1;
ps2 += poly2;

ps3 += ps1 & ps2;
ps4 += ps1 | ps2;
ps5 += (ps4 - ps3);

std::cout << ps3 << std::endl;
std::cout << ps4 << std::endl;
std::cout << ps5 << std::endl;


return 0;
}


2009年11月5日木曜日

ジニ係数に現れないもの

 竹中平蔵先生のおっしゃっていたジニ係数が悪くないという論旨が、どうにも、ひっかかるので、考察してみました。生活をする単位は、家族なわけでして、昔であれば男性一人が働いて家族を養っていたのだと思います。ところが、男性一人の収入では足りなくて、共働きしているというケースが増えているのでは?という気がしてしょうがないのです。こういうものは、ジニ係数では測れないと思います。生活最低水準を維持するために、一方では余裕の時間が減る、または、心身を削る事になると思います。収入という面で換算すれば負荷がかかって折れ曲がる寸前の棒は多少悪化しても、見かけ上は折れていません。ジニ係数で見れば、少し悪くなっているかもしれない程度の現象にしか見えないと感じます。
 

2009年11月4日水曜日

カヤックしてない

 今シーズンは、千歳川に肩慣らしに2回行っただけ…。せめて空知川か幾春別川ぐらいは行きたかった。現在持っている T1 はスピードが遅くて、もうちょい速い艇が欲しいところ。そこで、リバーサーフィンならぬネットサーフィン…。Dragorossi Fish に惹かれるけど、買えないよなぁ…。

2009年11月2日月曜日

仮面ライダー555コレクション

 オークションについて(ニッチ市場の勉強)を長々と書きましたが、コレクションを振り返って見ることに…。現在4歳のうちの息子には、高すぎて見せる事すら出来ない状況です。成長して、いつの日か、このブログを発見して愕然とする日がやってくるのでしょうか?まぁ、スイッチが入ってしまって、嫁さんにも呆れられてしまったと思います。視線が痛々しかったです。何か届く度に「また何か頼んだ?」と…。ファイズ・ショットは箱の状態が悪くてテンションが下がりました。それにカイザ・ショットはファイズ・ショットと違いは微差で、カイザ・ショットは別にいいや…と本体だけの入手です。後でファイズ・ショットの本体抜きが出回ったので箱を入手して取り替えました。ファイズ・アクセルは、まとめて入手した関係でチャイニーズ版と日本版の2つを持ってます。ファイズ・ブラスターは、テレビシリーズでも後半にちょこっと出てきただけ、人工衛星からエネルギーを転送するという設定なので、屋内では使えないだろ…とか、まぁ、思い入れが無いので揃える気がありませんでしたが、多少気になったので欠品ながら入手しました。スマート・パッドも、まとめて入手した関係で、集める意志は無かったけどあります。こうやって、振り返ってみると、結構すごい事に…。つか、やりすぎだろ…orz。












2009年11月1日日曜日

使える!経済学の考え方 感想

 「使える!経済学の考え方」 404 blog not Found で紹介されていて、面白そうなので購入しました。しかし、一部内容が難解です。数学の知識が、そんなに無くても読める感じで紹介されていましたが、途中、独立した事象の総和が1でない確率空間でない確率が登場し、かなり面食らいました。一般的な集合論が成立しないので、論理学も我々が一般的に考える論理学の枠組みでは考えられず、体系自体が無矛盾かどうかを考えなければならない数学の世界が、サラリと語られてます…。ここは、ちょっと理解できませんでした。
 久しぶりに日曜日の朝にテレビを見ていたら、竹中平蔵先生が出演されていて、日本はジニ係数が、そんなに悪くないのに、日本では、あたかも格差が広がっているような言葉だけが一人歩きしていると主張されていて、へー、ジニ係数だ!と、この論点を理解できた事に嬉しくなりました。
 このジニ係数ですが、専業主婦等も含めた試算、年間所得だけを比較した試算、保有資産も含めた試算、などなど、とり方によって傾向が変わってきそうで、ちょっと気になりました。こんな事を思考できるのも本書のおかげです。
 第6章のケインズが何故注目されているかを解説したあたりは、以前に世界危機のセミナーを受けた時に紹介された本が、どうして注目されているのかを伺い知る事ができて、良かったです。もう一度、再読してみようかな?という気になりました。
 若干、難解な部分も含まれていますが、今までの中で一番身になった本でした。理系の人は、この本からスタートしても良いのではないでしょうか?

クラウド版RAID5

パリティ付きストライプ・セットって、あるじゃないですか?あれのクラウド版を思いついてしまいました。ちょうど、W3Cにウェブ・ストレージとかの規格が上がってたんで、無料のディスク・サービスが 500M,500M,500M と三個所以上あれば、これら3つのクラウドを統合して、パリティ付きストライプ・セットとして 1G のディスク・サービスとして利用できちゃうんじゃないですか?
 2つのサービスが同時に崩壊しない限り大丈夫で、1つのサービスが崩壊しても、どこかから新しいサービスなり、スペースなりを追加すれば、クラウド・ホット・スワッピング…なんちゃって…。
 くだらねぇけど、うまく冗長化できれば、パブリック・クラウドでプライベート・クラウドを構築できちゃうとか…?