- PR -

C#の非同期ソケットについて

1
投稿者投稿内容
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2004-07-28 16:58
いつもお世話になっております。

ご存知の方がいらっしゃいましたら、C#のソケットに関してご意見をお願いいたします。

下は、個人的なC#の非同期ソケットの使用イメージです。
(間違っていたら、ご指摘お願いいたします。)

クライアント側ですが、一般的にMSDNの例では、

@下記3つの非同期CallBack関数を必要とする。

 ConnectCallBack
 SendCallBack
 RecvCallBack

A下記関数に引数として、受信バッファなど(小さなクラス)を渡すことで
 必要な処理を行う。

 BeginConnect
 BeginSend
 BeginRecieve

B非同期CallBack関数内で、引数を取得して下記で非同期処理を正常に完了させる。

 EndConnect
 EndSend
 EndReceive

Cまた非同期なので、マルチスレッド操作に対応させるためにManualResetEvent などで
 制御する。

自分なりに@〜Cを解釈し下記のようにプログラミングしました。
※現状では、動作上の問題は、発生していません。

@では、インスタンク関数(※staticでない関数)で実装しました。

Aでは、受信バッファなどに、自前のクラスオブジェクト(ClientSocketInfo:
ソケットオブジェクト自身をラップしたクラスオブジェクト)
 を引数にしました。
 →この理由は、RecvCallBack内で、受信バッファと受信バッファ長を計算する必要があるために
  arをキャストしただけで情報を取得できるからです。

public class ClientSocketInfo
{
int m_RecvBufSize;      //受信バッファの使用バイト数
byte[] RecvBuf[1024];     //受信バッファ
Socket m_CLSock; //クライアントソケット

 //CallBack関数(※実装は省略)
public void ConnectCallback(IAsyncResult ar)
public void ReceiveCallback( IAsyncResult ar )
public void SendCallback(IAsyncResult ar)
}

B EndConnect、EndSend、EndReceiveを実施しない場合は、通常通り実装しました。
  →ReceiveのCallBackの場合のみ、Begin〜関数を呼んでいます。
   これで、繰り返し非同期受信を処理できる。

Cの制御は、C#言語の『lock』を使用しました。
 ※これで、排他されるのかがいまいち不安です...

以上を踏まえて、お聞きしたいのですが、

【質問1】
非同期ソケットを使用する場合に、
一般的には、皆さんどのように実装されているのでしょうか?
また、デザインパターン的な使用方法(テンプレート的な使用方法?)は、
あるのでしょうか?

【質問2】
現在、相手側ソケットからのソケット切断を検地する方法は、
『受信電文長=0でRecvCallBack関数が呼ばれた場合』で判断しています。
これは、正しいのでしょうか?

【質問3】
また、CallBack内で例外が発生して、EndConnect、EndSend、EndReceiveを
実施できない(実施できなかった)場合は、どのように対処したらいいのでしょうか?
『ソケットを切断してから再接続』などでしょうか?

続いてサーバソケットですが、
【質問4】
listener.Listen(100);
などと書くと、100個のクライアントと同時に接続できるとMSDNにあります。
この場合、100個のクライアントと同時に接続して、その後で全て切断すれば
、また新規のクライアントと接続できるのでしょうか?

★サーバソケットに関しては、これから初実装になりますので、
 また書込みをすることもあると思いますが、その際はよろしくお願いいたします。

以上、お忙しいとは思いますが、よろしくお願いいたします。
隣の古柴
ベテラン
会議室デビュー日: 2004/06/04
投稿数: 94
投稿日時: 2004-07-29 10:00
はじめまして。半人前です。

存知てはいませんが、つい最近まで四苦八苦してました関係で情報くらいは。。。
(参考になればいいのですが)

引用:

@では、インスタンク関数(※staticでない関数)で実装しました。



み・・、見せてもらえませんか?

それと、よろしければ
 1.BeginAcceptとそのコールバック
 2.BeginReceiveとそのコールバック
はどう実装させたのかもお聞かせ頂きたいです。

引用:

Cの制御は、C#言語の『lock』を使用しました。
 ※これで、排他されるのかがいまいち不安です...



Cの制御とはMSDNのサンプルにものっているManualResetEventの
Reset、WaitOne、Set
の3点セットでの制御のことですか?
ちょっとここよくわからないもので。。。

引用:

【質問1】
非同期ソケットを使用する場合に、
一般的には、皆さんどのように実装されているのでしょうか?
また、デザインパターン的な使用方法(テンプレート的な使用方法?)は、
あるのでしょうか?



拙はMSDNの「非同期クライアントの例」「非同期サーバーの例」をまんま参考にしました(^^;

引用:

【質問2】
現在、相手側ソケットからのソケット切断を検地する方法は、
『受信電文長=0でRecvCallBack関数が呼ばれた場合』で判断しています。
これは、正しいのでしょうか?



拙も同じです。他の方法があれば後学のために>どなたか

引用:

【質問3】
また、CallBack内で例外が発生して、EndConnect、EndSend、EndReceiveを
実施できない(実施できなかった)場合は、どのように対処したらいいのでしょうか?
『ソケットを切断してから再接続』などでしょうか?



問題ないと思います。


引用:

【質問4】
listener.Listen(100);
などと書くと、100個のクライアントと同時に接続できるとMSDNにあります。
この場合、100個のクライアントと同時に接続して、その後で全て切断すれば
、また新規のクライアントと接続できるのでしょうか?



記述が紛らわしいのか、それともホントにそう(接続できる)なのかハッキリしてませんが
Listenに渡す引数は、バークレーソケットやWINSOCKのライブラリでは待ち行列数を意味し
ています。誤訳のような気が。。。してます。

隣の古柴
ベテラン
会議室デビュー日: 2004/06/04
投稿数: 94
投稿日時: 2004-07-29 13:46
半人前です。すいません、誤読により全然噛み合ってない個所がありましたので訂正させて
ください。

引用:


引用:

【質問1】
非同期ソケットを使用する場合に、
一般的には、皆さんどのように実装されているのでしょうか?
また、デザインパターン的な使用方法(テンプレート的な使用方法?)は、
あるのでしょうか?



拙はMSDNの「非同期クライアントの例」「非同期サーバーの例」をまんま参考にしました(^^;




何らかの雛型への落とし込みはできていません。
ですので「まんま参考にした」というのは答えになっていませんね。
大変失礼しました。

1

スキルアップ/キャリアアップ(JOB@IT)