1


私はいくつかの基本的なソケットメッセージングを行っています。うまく機能するルーチンがありますが、負荷がかかっていると問題が発生します。

私はUDPを使用してコネクションレス型のSendToを実行し、基本的にpingのような操作を実行して、LAN上にリスナーが存在するかどうかを確認しています。理想的にはブロードキャストアドレスを使用するだけですが、ワイヤレスルーターは私のブロードキャストを中継していないようです。私の回避策は、サブネット上のすべてのIPを反復処理し、データグラムを各IPに送信することです。他のPCはリッスンしていて、メッセージを受け取った場合は返信します。これにより、ピアはお互いを見つけることができます。サブネット内の各IPにデータグラムを送信するループ内のコードは次のとおりです。

            string msgStr = "some message here...";
            byte[] sendbuf = Encoding.ASCII.GetBytes(msgStr);

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Blocking = true;
            socket.SendTo(sendbuf, remoteEndPt);
            //socket.Close();

これは機能しますが、サブネット範囲が大きい場合、たとえば255.255.0.0(反復するIPが最大60,000)の場合、最終的にエラーコード「10022」で「無効な引数」を意味するSocketExceptionが発生します。これは、送信が約10,000回成功した後に発生する傾向があり、このエラーが発生し始めます。また、私が職場で使用しているルーターはそれを処理し、おそらく高出力ルーターですが、私のラボの安価なルーターがエラーを発生させます。

SocketExceptionをキャッチした後、ループを再開する前に待機時間を置くと、通常は回復しますが、最終的には再びエラーが発生します。

ルーターのバッファーがいっぱいになり、データを送信できなくなったことが原因だと思います。仕事でより高品質のものはそれを処理することができますが、安価なものは行き詰まります。それはもっともらしいと思いますか?

いくつかの質問:

1)コネクションレス型の方法でSendToを使用する場合、ソケットでClose()を呼び出す必要がありますか?

Close()を呼び出すことによる利点は見られませんでしたが、Close()を呼び出すと、反復が大幅に遅くなります(速度が大幅に低下するため、上記でコメントアウトしています)。これは意味がありますか?

2)さらにデータを送信する前に待つ必要があることを通知する方法はありますか?例外をキャッチするのは正しくないようですが、その原因はまだわかりません。

ありがとう、J。

4

1 に答える 1

2

それがルーターだけであるかどうかはわかりませんが、OSでも何らかの制限が発生していると思われます...

Socket送信するたびにを作成している理由はありますか? 再利用するだけで...

とにかくhttp://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspxShutdown()によると、呼び出してClose()からSocket...おそらく送信ごとではなく、255ごとに呼び出すことをお勧めしますIPとか…

チェックアウトUdpClient- 実装がより簡単/より堅牢になる可能性があります

編集 - コメントによると:

ソケットの再利用「キャッシュ」が必要な場合...これにより、たとえば、特定のソケットが256チェックごとにのみ使用されるようになります...

// build/fill your Socket-Queue for example in the con
class SocketExample
{
    Queue<Socket> a = new Queue<Socket>();
    SocketExample ()
    {
        int ii = 0, C = 256;
        for (ii = 0; ii < C; C++)
        {
            a.Enqueue (new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp));
        }
    }

    // in your function you just dequeue a Socket and use it, 
    // after you are finished you enqueue it
    void CheckNetIP (some parameters...)
    {
        Socket S = a.Dequeue();
        // do whatever you want to do...
        // IF there is no exception
        a.Enqueue(S); 
    }
}
于 2011-08-13T02:10:39.357 に答える