小ネタですが、TcpListenerのおそらくよさげな使い方についてです。ポイントは、TcpListenerはAccept要求をキューに溜め込む仕様のため、Acceptの処理をすばやく実行しないと、新しい要求が失敗する可能性があるということです。
とりあえずコード(C#)
// TcpListenerの使用例
// クライアントとのデータのやり取りはここでやる(Thread)
void ConnectionProc(object target)
{
TcpClient tcpClient = (TcpClient)target;
// ここでtcpClientからストリームを取得してReadとかWriteとかCloseとかを実行する
// ちなみにクライアント側から接続が切断されると、Readでサイズ0が返ってくる
}
// 接続を受け入れる。
void AcceptConnection(TcpListener tcpListener)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
Thread thread = new Thread(ConnectionProc);
thread.IsBackground = true;
thread.Start(tcpClient);
}
// Acceptを受け入れる処理(Thread)
void AcceptProc(object target)
{
TcpListener tcpListener = (TcpListener)target;
while (true)
{
try
{
while (tcpListener.Pending())
{
AcceptConnection(tcpListener);
}
AcceptConnection(tcpListener);
}
catch (Exception)
{
// TcpListenter.Stop()が呼び出されるとSocketExceptionがThrowされる
break;
}
}
}
// Acceptを開始する処理
// tcpListenerはどこかで作成されているとする
tcpListener.Start();
Thread thread = new Thread(AcceptProc);
thread.IsBackground = true;
thread.Start(tcpListener);
正直言ってwhile (tcpListener.Pending()){…}
のコードはロジック的にはなくても同じに思えるのですが、どうやらこのように書いておくと、Acceptを処理しているときに直ぐに別な接続が来た場合、早く応答するようです。
もし、TcpListenerを使っていて、クライアントからの接続に失敗するようだったら、このような方法を試してみるのがいいかもしれません。
0 件のコメント:
コメントを投稿