1

I'm trying to stream a video feed form the Xbox Kinect from a client to a server. I got it working with TCP but I could only get about 5 fps so now I'm trying it with UDP. UDP should be faster because of how the protocol works but it seems to be slower. Here is my post about the TCP (http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient)

I can send this all the data I want over my LAN but I start losing a lot of packets if I push them out too fast. That is why I am using the Thread.Sleep(20); Increasing the chuck size speeds it up a lot but I'm at my max for sending over my LAN and if I understand correctly the max chunk size for sending over the internet is about 1500 bytes. If I only sent 1500 bytes at a time this would go really slow. I must be doing something wrong.

Here is the code.

    private const int constChunkSize = 38400;
    protected UdpClient udpObject;

    private void HandleComm()
    {
        byte[] fullMessage = new byte[1228800];
        byte[] byteReceived;
        int currentIndex = 0;
        IPEndPoint remoteIPEndPoint = new IPEndPoint(ip, port);
        while (true)
        {                
            byteReceived = udpObject.Receive(ref remoteIPEndPoint);

            if (currentIndex + byteReceived.Length > 1228800)
            {
                int wtf = 0;
            }
            Array.Copy(byteReceived, 0, fullMessage, currentIndex, byteReceived.Length);
            currentIndex += byteReceived.Length;
            //Console.WriteLine("Recieved: " + currentIndex);
            if (currentIndex == 1228800)
            {
                if (OnDataReceived != null)
                {
                    FrameReceivedArgs args = new FrameReceivedArgs();
                    args.frame = new byte[fullMessage.Length];
                    fullMessage.CopyTo(args.frame, 0);
                    OnDataReceived(this, args);
                }
                currentIndex = 0;
                Console.WriteLine("Done receiving" + DateTime.Now.Ticks);
            }
        }            
    }

    public void sendData(byte[] data)
    {
        sending = true;
        sendThread = new Thread(sendDataThread);
        sendThread.Priority = ThreadPriority.Highest;
        sendThread.Start(data);            
    }

    private void sendDataThread(object tempData)
    {
        byte[] data = (byte[]) tempData;
        int totalBytes = data.Length;
        int currentBytes = 0;
        int bufferLength = constChunkSize;
        byte[] sendBytes = new byte[constChunkSize];

        while (currentBytes < totalBytes)
        {
            if (totalBytes - currentBytes < constChunkSize)
                bufferLength = totalBytes - currentBytes;

            Array.Copy(data, currentBytes, sendBytes, 0, bufferLength);

            currentBytes += bufferLength;
            udpObject.BeginSend(sendBytes, bufferLength, new AsyncCallback(sendingData), udpObject);
            Thread.Sleep(20);
            //Console.WriteLine("Sent: " + currentBytes);
        }
        Console.WriteLine("done sending" + DateTime.Now.Ticks);
        sending = false;
    }

    private void sendingData(IAsyncResult ar)
    {            
        udpObject.EndSend(ar);
    }
Rickyman35
  • 165
  • 3
  • 11
  • Why are you using `BeginSend` + `Sleep`? That is a: not safe (you don't **know** that it is done after 20ms), and b: could be unnecessarily slow (it could have finished sooner). If you don't want to use the async API, then: don't - just use `Send`...? Actually, you are **required** to call `EndSend` if you are using `BeginSend`, to catch any exceptions, and to ensure you don't leak. – Marc Gravell Mar 09 '12 at 06:38
  • I do call EndSend. The reason I sleep is because if I don't it will just lose the packets. For some reason if you send packets really fast it just drops most of them, even over LAN. – Rickyman35 Mar 09 '12 at 16:34
  • my apologies on not calling EndSend - however, there is still a timing issue; you should call the next BeginSend in the callback, after calling EndSend. Maybe doing that would allow you to remove the Sleep, which should fix the performance issue – Marc Gravell Mar 09 '12 at 17:35
  • I'm not sure what the problem was but I ended up getting it to work with TCP. Here is the thread: http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient – Rickyman35 Mar 12 '12 at 16:59
  • Increasing the chunk size above the MTU (1500 chars) is likely to make things worse as the packet will have to be fragmented and the loss of any fragment will result in the loss of the entire packet. Of course if you sleep between every packet it will be much slower. What does onDataReceive do? The better practice would be to do as little processing as possible in the receiving thread and dispatch packets to worker threads. At that point you can get rid of your Sleep(20) – mac Mar 13 '12 at 17:04

0 Answers0