8

いくつかのマルチキャスト チュートリアルを適応させて、パケットの送信方法を変更しました。

私の場合、 size のパケットのキューを作成し、その後、すべてのオンライン ネットワーク アダプターbytes[1024]経由で送信されます。Socket.Send()

問題:

送信時、呼び出された別のメソッドreceiveMessage()が別のスレッドで実行されています。を使用Socket.Bind()してパケットをキャプチャしますが、キャプチャされるパケットは 1 つだけです。

あまりにも多くの処理を行っているため、受信したパケットが遅延 (および損失) していますか?

アップデート

着信パケットのキューを追加することを検討しているため、1 つのスレッドがキャプチャして保存し、2 つ目のスレッドがパケットを処理します。

Send メソッド

Socket _listener_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

foreach (IPAddress localIP in Dns.GetHostAddresses(Dns.GetHostName()).Where(i => i.AddressFamily == AddressFamily.InterNetwork))
{
    //handle image and files                
    _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_MultiIP, localIP));
    _listener_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 1);
    _listener_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    _listener_socket.MulticastLoopback = true;
    _listener_socket.Connect(new IPEndPoint(_MultiIP, _PORT));

    int count = MSGS_TO_SEND.Count;

    while (count > 0)
    {
        count--;
        byte[] temp = (byte[])(MSGS_TO_SEND.Dequeue());
        _listener_socket.Send(temp, _BYTE_BUFFER_SIZE, SocketFlags.None);
        MSGS_TO_SEND.Enqueue(temp);
    }              

    //----------------------------------------------
    //-------------------SEND DATA------------------
    //----------------------------------------------
}

_listener_socket.Close();

受け取り方法

//initialise multicast group and bind to interface
Socket _sender_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, _PORT);
_sender_socket.Bind(ipep);

IPAddress localip = _MultiIP;
_sender_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(localip, IPAddress.Any));

//{
while (_sender_socket.IsBound && !bStop)
{
    byte[] b = new byte[_BYTE_BUFFER_SIZE];
    _sender_socket.Receive(b);
    char[] chars = new char[_BYTE_BUFFER_SIZE];
    System.Buffer.BlockCopy(b, 0, chars, 0, b.Length);

    string _message = new string(chars).Trim();
    string ip = _message.Substring(0, _message.IndexOf("~"));
    _message = _message.Remove(0, _message.IndexOf("~") + 1);
    string _flag = _message.Substring(0, _message.IndexOf("~"));
    _message = _message.Remove(0, _message.IndexOf("~") + 1);

    _message = _message.Replace("\0", string.Empty);

    ip = "1.0";
    icount++;
    handleData(ip, _flag, _message);
}
4

2 に答える 2

1

試したくない場合は、完全に機能する例を次に示します: https://github.com/efaruk/playground/tree/master/Multicasting

必要に応じて、これらの再利用可能なコンポーネント ( MulticastSenderMulticastReceiver、) をプロジェクトで使用できます...

于 2016-01-24T21:18:35.843 に答える
0

送信者は、メンバーシップをバインドまたは追加する必要はありません。どのデータグラム ソケットも、マルチキャスト アドレスに送信できます。受信者は、マルチキャスト アドレスにメンバーシップを追加する必要があります。送信者と受信者もポートに同意する必要があります (受信者はポートにバインドする必要があります)。

各例のマルチキャスト オプションでは、引数が逆になっています。

ソケットには既にカーネルからのバッファリングがあるため、メッセージ キューでコードを複雑にする必要はありません。

于 2016-01-26T18:47:39.823 に答える