4

リモート ホストから UDP データを受信する C# アプリケーションがあります。ソケットが何も受信しないことがあり、その理由についての手がかりが見つからないようです! Wireshark は、データがリモート デバイスから正しく送信されていることを示しています。なぜうまく受信できる場合とできない場合があるのか​​ わかりません。

例外は発生しませんが、OnRecieve が呼び出されることはありません

これが役立つ場合に備えて、私のコードは次のとおりです。

class cUdpRx
{
    private Thread rxThread = null;
    private Socket UdpSocket;
    private IPEndPoint localEp;
    byte[] byData;
    //rxbytes event
    public delegate void OnRxBytesEventHandler(byte[] rxBuf);
    public event OnRxBytesEventHandler OnRxBytesEvent;



    /// <summary>
    /// Creates the udp socket
    /// </summary>
    /// <param name="Port"></param>
    /// <returns></returns>
    public bool CreateSocket(int Port)
    {
        try
        {
            byData = new byte[1500]; //create our buffer
            UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            localEp = new IPEndPoint(IPAddress.Any,Port);
            UdpSocket.Bind(localEp);
            UdpSocket.BeginReceive(byData,0,byData.Length, SocketFlags.None, new AsyncCallback(OnRecieve), UdpSocket);

            return true;    //seemed to work ok
        }
        catch
        {
            Dispose();
            return false;   //something went wrong, abort
        }
    }

    private void OnRecieve(IAsyncResult iar)
    {
        byte[] rxData;
        int nBytesRec = 0;
        Socket socket = (Socket)iar.AsyncState;
        try //in case something else has already disposed of the socket
        {
            nBytesRec = socket.EndReceive(iar);
        }
        catch
        {
            Debug.WriteLine("cant access udp rx socket");
        }
        try
        {
            if (nBytesRec > 0)
            {
                rxData = new byte[nBytesRec];
                Array.Copy(byData, rxData, nBytesRec); //copy exact data into new array
                OnRxBytesEvent(rxData);
            }
            if(!killThreads)
                UdpSocket.BeginReceive(byData, 0, byData.Length, SocketFlags.None, new AsyncCallback(OnRecieve), UdpSocket);
        }
        catch(SocketException se)
        {
            Debug.WriteLine(se.ToString());
        }
    }

私のプロジェクトを進めるのを妨げているので、どんな助けも本当に感謝しています。ありがとう

更新 IPAdress.any の使用が問題のようです。私が変更した場合:

localEp = new IPEndPoint(IPAddress.Any,Port);

localEp = new IPEndPoint(IPAddress.Parse("192.168.0.33"),Port);

ここで、192.168.0.33 は私のコンピューターの IP アドレスで、毎回データを受信します。誰でも理由を説明できますか?IPAddress.any を使用して、無線接続と有線接続の両方から受信すると非常に便利です。IPAddress.any は 0.0.0.0 に相当し、MSDN によると、すべてのネットワーク インターフェイスで受信する必要があります。

4

2 に答える 2

1

このような問題の通常の原因は、パケットの処理速度が十分でないことです。それらはソケット受信バッファをいっぱいにし、カーネルはそれらをドロップし始めます。

トラフィックバーストに対応するために、ソケット受信バッファサイズを増やします。高速ソケット読み取りパスから不要なものをすべて削除します。スレッドプールに対して作業する代わりに、以下の単純な反復アプローチを検討してください。

rxData = new byte[nBytesRec];

while ( !time_to_stop ) {
    int len = socket.Receive( rxData );
    OnRxBytesEvent( rxData, len );
}

あなたのコードコメントはマルチキャストについて言及しています。そのために明示的なグループメンバーシップを追加する必要があり、インターフェイスでマルチキャストグループに参加するという事実(明示的にまたはルーティングテーブルを介して決定される)があるため、2つのインターフェイスでマルチキャストデータをリッスンする場合は、2つ必要です。ソケット。

于 2012-08-03T16:21:48.527 に答える