UDPClient Async BeginReceive is very slow

I use UDPClient to send a multicast request and receive a response from various clients on the network. I can send a request as well as receive a response, but the response I receive is very slow. It takes 2-3 minutes to get an answer from all customers. When sending a request to the network, I checked in WireShark, there I see the answer in milliseconds from all clients only in the test program. It takes a lot of time. Can someone please indicate what error I can make? Below is the code. Please help me with this. I am stuck on this issue for the last 2 days.

public class Trinity_WSDiscovery : IDiscoveryService 
{
        #region IDiscoveryService Members
        public event EventHandler FoundNewDevice;
        public event EventHandler EndOfDiscovery;
        DeviceBinding m_DeviceBinding;
        bool IsFindComplete = false;
        Thread receiveThread;
        UdpClient sock ;        
        IPEndPoint RemoteIpEndPoint = new IPEndPoint(System.Net.IPAddress.Any, 0);
        IPEndPoint iep = new IPEndPoint(System.Net.IPAddress.Parse("239.255.255.250"), 3702);
        UdpState udpState = new UdpState();
        XmlDocument xmlDoc = new XmlDocument();

    public void Start()
    {
        //Need to create new object every time we start discovery because
        //every time udp buffer needs to be flushed and restarted
        sock = new UdpClient();
        string str = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:wsadis=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:dn=\"http://www.onvif.org/ver10/network/wsdl\"><soap:Header><wsadis:MessageID>uuid:" + System.Guid.NewGuid().ToString() + "</wsadis:MessageID><wsadis:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsadis:To><wsadis:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsadis:Action></soap:Header><soap:Body><d:Probe><d:Types /> <d:Scopes/></d:Probe></soap:Body></soap:Envelope>";
        byte[] data = Encoding.ASCII.GetBytes(str);
        sock.Send(data, data.Length, iep);
        sock.JoinMulticastGroup(System.Net.IPAddress.Parse("239.255.255.250"));            
        IPEndPoint iep1 = new IPEndPoint(System.Net.IPAddress.Any, 0);            
        udpState.ipEndpt = RemoteIpEndPoint;
        udpState.udpClient = sock;           
        BeginReceive();           
    }

    public void BeginReceive()
    {
        Thread.Sleep(100);
        if (sock.Available > 0)
        {
            sock.BeginReceive(new AsyncCallback(ReceiveCallback), udpState);
        }
        else
        {
            FindComplete();
        }
    }

    public void ReceiveCallback(IAsyncResult ar)
    {
        UdpClient udpClient = (UdpClient)((UdpState)(ar.AsyncState)).udpClient;
        IPEndPoint ipEndpt = (IPEndPoint)((UdpState)(ar.AsyncState)).ipEndpt;
        Byte[] receiveBytes = udpClient.EndReceive(ar, ref ipEndpt);
        string receiveString = Encoding.ASCII.GetString(receiveBytes);
        if (receiveString.Contains("NetworkVideoTransmitter"))
        {
            xmlDoc.LoadXml(receiveString);
            XmlNodeList list = xmlDoc.GetElementsByTagName("XAddrs", "http://schemas.xmlsoap.org/ws/2005/04/discovery");
            XmlNode node = list[0];
            string strEndPoints = node.FirstChild.Value;
            string[] strEndPointList = Regex.Split(strEndPoints, " ");
            OnFoundDevice(strEndPointList);
        }
        BeginReceive();
    }

} `

+3
source share
3 answers

Why do you need to Thread.Sleep?

This may cause delays.

+1

.

  • , 100 . , BeginReceive, - , , . () BeginReceive, . ReceiveCallback, 100 . 30 , 3 .

  • ReceiveCallback OnFoundDevice. . . 1 , 1 ( 100 BeginReceive).

: 1. BeginReceive, .

public void BeginReceive()
{
     sock.BeginReceive(new AsyncCallback(ReceiveCallback), udpState);
}
  • , OnFoundDevice. , (, QueueUserWorkItem threadpool).

, BeginReceive, , , , "" "" .

, .

+1

you could use a timeout with a blocking call like this ... because it looks like your program doesn't want to do any other work while it still waits .. this way, if the answer comes in less than 100 ms, t wait so long.

udpAdmin.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100)
receiveBytes = sock.Receive(RemoteIpEndPoint)  'waits here till you get a response or until timeout, whichever comes first.
0
source

All Articles