none
loss some data when send and recieve data using udp C# RRS feed

  • Question

  • Hello everyone

    i don't know if this forum is right place to write my question or not.

    i create app on my pc to send and receive data using udp protocol. i use code to monitor data recieving on my server and i found some data lossing when sending from my pc.

    I'm trying to solve this issue for long time but i fall

    my pc internet connection is fiper optic download (60 Mbps) upload (15Mbps)

    Can anyone help me to fix this problem and save my time, please?
    these are codes that i use on my pc

    code of sending:

            public async Task LinesAsPara(LineCollection Lines)
            {
                CancelTask = false;
                taskToken = new CancellationTokenSource();
                CancellationToken ct = taskToken.Token;
    
                if (Monitor.IsEntered(syncObj))
                {
                    paused = false;
                    Monitor.Exit(syncObj);
                }
    
                WatchTest.Start();
    
                Task task = new Task(() => {
                    foreach (var Oneline in ltlTextArea.TextArea.Lines)
                    {
    
                        try
                        {
    
                            CheckForIllegalCrossThreadCalls = false;
    
                            string pattern = @"(?:CACHE PEER|cache peer):\s*(\S+)+\s+(\d*)";
    
                            foreach (Match m in Regex.Matches(Oneline.Text, pattern))
                            {
                                Server = Dns.GetHostAddresses(m.Groups[1].Value)[0];
                                RemotePort = Convert.ToInt32(m.Groups[2].Value);
                                CachePeer = m.Groups[0].Value;
                            }
    
                            IPEndPoint ipeSender = new IPEndPoint(Server, RemotePort);
                            //The epSender identifies the incoming clients
                            EndPoint epSender = (EndPoint)ipeSender;
    
                            int ID = 0;
                            byte[] buf = new byte[32];
                            buf[0] = TYPE_PINGREQ;
    
                            // Self Program Use
                            buf[1] = 0x4D;
                            buf[2] = 0x43;
                            buf[3] = 0; // ping packet number
                            buf[4] = (byte)(Oneline.Index >> 8);
                            buf[5] = (byte)(Oneline.Index & 0xff);
                            // Multics Identification
                            buf[6] = (byte)ID; // unused must be zero (for next use)
                            buf[7] = (byte)('M' ^ buf[1] ^ buf[2] ^ buf[3] ^ buf[4] ^ buf[5] ^ buf[6]); // Multics Checksum
                            buf[8] = (byte)'M'; // Multics ID
                                                //Port
                            buf[9] = 0;
                            buf[10] = 0;
                            buf[11] = (byte)((int)CachePort.Value >> 8);
                            buf[12] = (byte)((int)CachePort.Value & 0xff);
                            //Program
                            buf[13] = 0x01; //ID
                            buf[14] = 7; //LEN
                            buf[15] = (byte)'M';
                            buf[16] = (byte)'u';
                            buf[17] = (byte)'l';
                            buf[18] = (byte)'t';
                            buf[19] = (byte)'i';
                            buf[20] = (byte)'C';
                            buf[21] = (byte)'S';
                            //Version
                            buf[22] = 0x02; //ID
                                            //	if (REVISION<100) {
                            buf[23] = 3; //LEN
                            buf[24] = (byte)'r';
                            int REVISION = 81;
                            buf[25] = (byte)('0' + (REVISION / 10));
                            buf[26] = (byte)('0' + (REVISION % 10));
    
    
    
                            MainCSP CSPPeer = new MainCSP
                            {
                                //CachePort = (int)CachePort.Value,
                                MSec = Oneline.Index,
                                CachePeer = CachePeer
                            };
                            PeerList.Add(CSPPeer);
    
                            serverSocket.BeginSendTo(buf, 0, buf.Length, SocketFlags.None, epSender, new AsyncCallback(OnSend), null);
                            sendDone.WaitOne();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "SGSServerUDP1",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
    
                    }
    
                });
                task.Start();
    
                WatchTest.Stop();
                ShowWatch.Stop();
                StopwatchBut.Text = string.Format("{0}D {1}h : {2}m : {3}.{4}s", WatchTest.Elapsed.Days, WatchTest.Elapsed.Hours, WatchTest.Elapsed.Minutes, WatchTest.Elapsed.Seconds, WatchTest.Elapsed.Milliseconds);
                Form1.IsVoice = SpeakerSwitch.Value;
                VoiceButtonItem.PerformClick();
                DesktopAlert.Show();
                DesktopAlert.CaptionText = string.Format("Lines Tester (ID:{0})", Form1.SessionID);
                DesktopAlert.ContentText = string.Format("The test is completed." + Environment.NewLine + "||Working({0})||Syntax({1})||Other({2})||", WorkBtn.Counter.Text, SyntaxBtn.Counter.Text, OtherBtn.Counter.Text);
                ltlStartButton.Enabled = true;
            }
    
            public void OnSend(IAsyncResult ar)
            {
    
                try
                {
    
                    serverSocket.EndSend(ar);
                    sendDone.Set();
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "SGSServerUDP2", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

    code of recieving:

            void Receive()
            {
    
                try
                {
                    CheckForIllegalCrossThreadCalls = false;
    
                    //We are using UDP sockets
                    serverSocket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Dgram, ProtocolType.Udp);
    
                    //Assign the any IP of the machine and listen on port number 1000
                    IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, (int)CachePort.Value);
    
                    //Bind this address to the server
                    serverSocket.Bind(ipEndPoint);
    
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                    //The epSender identifies the incoming clients
                    EndPoint epSender = (EndPoint)ipeSender;
    
                    //Start receiving data
                    serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length,
                        SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "SGSServerUDP3",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
    
            private void OnReceive(IAsyncResult ar)
            {
                try
                {
                    IPEndPoint ipeSender = new IPEndPoint(IPAddress.Any, 0);
                    EndPoint epSender = (EndPoint)ipeSender;
    
                    serverSocket.EndReceiveFrom(ar, ref epSender);
    
                    const int TYPE_PINGRPL = 4;
                    switch (byteData[0])
                    {
                        case TYPE_PINGRPL:
                            int result = PeerList.FindIndex(x => x.MSec == ((byteData[4] << 8) | byteData[5]));
                            if (result != -1)
                            {
                                WorkBtn.AddData(PeerList[result].CachePeer + "(" + ((byteData[4] << 8) | byteData[5]) + ")" + Environment.NewLine);
                                DesktopAlert.ContentText = string.Format("The test is completed." + Environment.NewLine + "||Working({0})||Syntax({1})||Other({2})||", WorkBtn.Counter.Text, SyntaxBtn.Counter.Text, OtherBtn.Counter.Text);
                                PeerList.RemoveAt(result);
                            }
                            break;
                    }
                    serverSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref epSender, new AsyncCallback(OnReceive), epSender);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "SGSServerUDP4", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

    Thank you



    • Edited by alphashow Saturday, February 2, 2019 11:54 AM
    Saturday, February 2, 2019 11:50 AM

All replies

  • You have to implement your "packet loss detection and resend" machnism if you choose to use UDP.

    If you want this part handled for you automatically, use TCP instead. (However in that case you'll need to handle connection lost-reconnection scenario)

    ======

    I'd create a TryParsePacket() function to throw exception when the data is found to be corrupted, and then send a packet to ask remote side to resend this sequence number in packet.

    And the remote side need to cache the sent packets for some time, preferrable in some circular buffer. When received resend request it should either send the lost packet or just resend every packet with sequence number larger than the requested sequence number.

    Depending on the method you choose, the local side may need to cache any packets received and sort them into order.

    There's a lot of work to do, and they cannot be done by others without specification of your messages (if you want the "generic" way, you should just switch back to TCP/IP, where the transportation layer handle it for you, instead of reinventing the wheel).

    Monday, February 4, 2019 1:22 AM
    Answerer