2015-09-07 3 views
8

В моей адаптации нескольких обучающих программ для многоадресной передачи я изменил метод отправки пакетов.Многоадресные пакеты: вопросы отправки и получения

В моем случае, я создаю очереди пакетов размером bytes[1024], после чего он отправляется через Socket.Send() по всем интернет-сетевые адаптеры

Проблема:

При отправке, другой метод, называемый receiveMessage() является работает на отдельном потоке. Используя Socket.Bind(), он захватывает пакеты, но захватывается только 1 пакет.

Я делаю слишком много обработки, таким образом, задерживая (и теряя) полученные пакеты?

ОБНОВЛЕНИЕ

Я рассматривает возможность добавления очереди для входящих пакетов, таким образом, 1 тем захватывает и магазины, вторые обрабатывает пакеты.

SendMethod

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); 
} 

ответ

0

Отправитель не обязан связывать или добавлять членство. Любой сокет датаграммы может отправлять на многоадресный адрес. Получателю необходимо добавить членство в адрес многоадресной рассылки. Отправителю и получателю также необходимо согласовать порт (приемник должен быть привязан к порту.)

Параметры многоадресной передачи в каждом примере имеют противоположные аргументы.

Сокеты уже имеют буферизацию из ядра, поэтому вам не нужно усложнять свой код очередями сообщений.

Смежные вопросы