1

I am Sending 68bytes of data using UDP Protocol.

68bytes of data consist of 4byte of int and random 64byte of byte array. uint seq starts with zero and it will increase if client send datagram to server once at a time. I used BitConverter.GetBytes for data's seq to make byte array.

public class NewData
{
    public uint seq;
    public byte[] data = new byte[64];

    public NewData()
    {
        seq = 0;
        data = null;
    }

    public NewData(uint seq, byte[] data)
    {
        this.seq = seq;
        this.data = data;
    }
}

Server has 2 Threads. 1 Thread will Enqueue and the other thread will Dequeue. (Producer and Consumer Thread)

I tried to check the data is coming well.

private readonly ConcurrentQueue<NewData> queue = new ConcurrentQueue<NewData>();


private void ReceiveThread()
{
    int recv;
    uint seq = 0;
    byte[] datagram = new byte[1024];
    List<byte> list = new List<byte>(); // for enqueue seq test

    while (true)
    {
        autoresetevent.WaitOne();

        if (Dispatcher.Invoke(() => (string)StartButton.Content == "Stop"))
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 

            socket.Bind(endpoint);
            socket.Blocking = false;

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, Dispatcher.Invoke(() => Convert.ToInt32(portTextBox.Text)));
            EndPoint tmpRemote = (EndPoint)sender;

            while (true)
            {
                try
                {
                    recv = socket.ReceiveFrom(datagram, ref tmpRemote);
                }
                catch (SocketException e)
                {
                    Thread.Sleep(threadSleep);  
                    continue;
                }

                ////------------------------------------------------------------------------
                //// To Test Datagram Sequence
                ////------------------------------------------------------------------------
                //for (int i = 0; i < 4; i++)
                //{
                //    list.Add(datagram[i]);
                //}
                //Debug.Write(Convert.ToString(BitConverter.ToUInt32(list.ToArray(), 0)) + " ");
                //list.Clear();

                NewData newdata = new NewData(seq, datagram);
                queue.Enqueue(newdata);

                ////------------------------------------------------------------------------
                //// To check queue Count. if, queue Count = Client packet sent, no packet lost 
                ////------------------------------------------------------------------------
                //Debug.Write(Convert.ToString(queue.Count()) + " ");

                seq++; 

                if (Dispatcher.Invoke(() => (string)StartButton.Content == "Start"))
                {
                    socket.Close();
                    break;
                }
                Thread.Sleep(threadSleep);
            }
        }
    }
}
private void FileSaveThread()
{
    uint packet_lost = 0;
    uint oldValue = 0;
    uint currentValue = 0;
    int j = 0; // for index

    List<byte> sequenceList = new List<byte>(); // sequenceList

    while (true)
    {
        autoresetevent2.WaitOne()
        NewData newdata = new NewData(); 

        if (queue.TryDequeue(out newdata))
        {
            for (j = 0; j < 4; j++)
                sequenceList.Add(newdata.data[j]);
            oldValue = BitConverter.ToUInt32(sequenceList.ToArray(), 0); // oldValue에 현재값 저장

            queue.TryPeek(out newdata);
            for (j = 0; j < 4; j++)
                sequenceList.Add(newdata.data[j]);
            currentValue = BitConverter.ToUInt32(sequenceList.ToArray(), 0); // oldValue에 현재값 저장
                                                                             //Debug.Write(Convert.ToString(currentValue) + " ");
            sequenceList.Clear();

            if (!(currentValue == oldValue + 1))
            {
                packet_lost++;
                Dispatcher.Invoke(() => dataResultTextBox.Text += " Packet_Lost : " + packet_lost + "\n");
            }
        }
        Thread.Sleep(threadSleep);
    }
}

The datagram's seq missing after 973.

Debug.Write () says ... 970 971 972 974 977 981 984 987 991 994 998 1001 1004 1007 1010 1014 1017 1021 1023 1027 1030 1034 1037 ...

Why does interval changed since the datagram sequence increased 1 at a time?

Or Should I think about other way to change byte array to Int?

Edit) I am sending data per 10ms. It works when i send data per 100ms.

client code

private async void DataSender(int num, int cycle, string ip, int port)
{

    uint dataSequence = 0; 

    byte[] data = new byte[64]; // 64byte data 
    byte[] byteDataSeq = new byte[4]; // int sequence to byte
    byte[] datagram = new byte[1024]; // seq + data
    List<byte> datagramList = new List<byte>(); 

    IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port); // 서버의 주소 지정
    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // udp 소켓 client 선언

    while (true)
    {
        if ((string)startButton.Content == "Start")
        {
            break;
        } 

        random.NextBytes(data); 

        byteDataSeq = BitConverter.GetBytes(dataSequence); 
        datagramList.AddRange(byteDataSeq); 
        datagramList.AddRange(data);

        datagram = datagramList.ToArray(); 
        datagramList.Clear(); 

        client.SendTo(datagram, ep); 
        dataSequence++;

        await Task.Delay(cycle);
    }
}

KooEunBam
  • 17
  • 1
  • 8
  • 1
    Maybe a packet loss, because this is udp. – shingo May 24 '22 at 05:48
  • It could be packet loss... I am sending data per 10ms. It works when I send data per 100ms. – KooEunBam May 24 '22 at 05:51
  • Packet loss can also be caused by receive buffer overflow. How do you send the data, how large is the data and the how long is the sleep time? An interval of 10ms worked but 100ms didn't seems unreasonable. – shingo May 24 '22 at 05:59
  • How can i control receive buffer overflow? – KooEunBam May 24 '22 at 06:03
  • Try a bigger `ReceiveBufferSize` to see if the missing number becomes larger. – shingo May 24 '22 at 06:06
  • You do not need the list, you can just do `BitConverter.ToUInt32(datagram, 0)`. The converter will ignore any extra bytes in the array. – JonasH May 24 '22 at 06:32
  • Also, do you have some special reason for using raw UDP? In most cases, a higher level protocol + library that can send arbitrary length messages will be easier to use. – JonasH May 24 '22 at 06:35
  • I tried bigger ReceiveBufferSize and I found, the data packet comes well, ConcurrentQueue Enqueues well, But tryDequeue lose some data. Is that possible? – KooEunBam May 24 '22 at 06:44
  • Reason why i ignored extra bytes in the array, I made datagram with 4 byte int and 64 byte array. I just need sequence which is 4 byte int that's why I used list. I need 64byte of array at the end, but I should find why debug write doesn't work well... (I thought extra bytes of array doesn't need in this question) – KooEunBam May 24 '22 at 06:46
  • I should use UDP Protocol to connect with Hardware. – KooEunBam May 24 '22 at 06:57
  • @shingo 10ms is losing packet. 100ms is working. I send data using UDP Protocol, client sleep time is what i type in WPF textbox (if i send data per 10ms, sleep time is 10ms.) . Server Thread sleep times are 50ms – KooEunBam May 24 '22 at 07:35
  • @KooEunBam two problems: 1) Please add code about `ConcurrentQueue`. 2) How could you know _"the data packet comes well, ConcurrentQueue Enqueues well, But tryDequeue lose some data"_? – shingo May 24 '22 at 07:43
  • @shingo 1) I added code about ConcurrentQueue. (I am worried about bunch of codes...) 2) I checked with debug.Write() and it worked with before 973 packet... – KooEunBam May 24 '22 at 08:02
  • @KooEunBam you were using the same `datagram` throughout and you didn't checked the return value of `TryPeek`. It's hard to imagine the problem didn't appear until 973. – shingo May 24 '22 at 08:46

1 Answers1

0

If Client sends data and sleep for 10ms, Dequeue Thread should not sleep more than 10ms. It should be more faster than sender.

For example, If you send data per 5ms, transaction per second will be 200 data. Then your Dequeue Thread should not sleep. Even 1 ms sleep will cause error.

Debug.Write will cause error too. If you try to print every data that socket received, Dequeue thread won't work properly.

KooEunBam
  • 17
  • 1
  • 8
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 20 '22 at 20:48