C#UDP速度比TCP慢

C#UDP速度比TCP慢,c#,video,tcp,udp,udpclient,C#,Video,Tcp,Udp,Udpclient,我正在尝试将Xbox Kinect的视频源从客户端传输到服务器。我用TCP实现了它,但我只能获得大约5 fps,所以现在我用UDP尝试。UDP应该更快,因为协议是如何工作的,但它似乎更慢。这是我关于TCP的帖子(http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient) 我可以通过局域网发送所有我想要的数据,但是如果我把数据包推得太快,我就会丢失很多数据包。这就是

我正在尝试将Xbox Kinect的视频源从客户端传输到服务器。我用TCP实现了它,但我只能获得大约5 fps,所以现在我用UDP尝试。UDP应该更快,因为协议是如何工作的,但它似乎更慢。这是我关于TCP的帖子(http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient)

我可以通过局域网发送所有我想要的数据,但是如果我把数据包推得太快,我就会丢失很多数据包。这就是为什么我要使用这个线程;增加卡盘大小可以大大加快速度,但我已经达到了通过LAN发送数据的最大值,如果我理解正确的话,通过internet发送数据的最大数据块大小约为1500字节。如果我一次只发送1500字节,速度会非常慢。我一定是做错了什么

这是代码

    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);
    }
private const int constChunkSize=38400;
受保护的UdpClient udpObject;
私有无效HandleComm()
{
字节[]完整消息=新字节[1228800];
字节[]byteReceived;
int currentIndex=0;
IPEndPoint remoteIPEndPoint=新IPEndPoint(ip,端口);
while(true)
{                
byteReceived=udpObject.Receive(参考remoteIPEndPoint);
如果(当前索引+字节接收长度>1228800)
{
int wtf=0;
}
Copy(byteReceived,0,fullMessage,currentIndex,byteReceived.Length);
currentIndex+=byteReceived.Length;
//Console.WriteLine(“接收:+currentIndex”);
如果(currentIndex==1228800)
{
如果(OnDataReceived!=null)
{
FrameReceivedArgs args=新FrameReceivedArgs();
args.frame=新字节[fullMessage.Length];
fullMessage.CopyTo(args.frame,0);
OnDataReceived(本,args);
}
currentIndex=0;
Console.WriteLine(“完成接收”+DateTime.Now.Ticks);
}
}            
}
公共void sendData(字节[]数据)
{
发送=真;
sendThread=新线程(sendDataThread);
sendThread.Priority=ThreadPriority.Highest;
sendThread.Start(数据);
}
私有void sendDataThread(对象tempData)
{
字节[]数据=(字节[])临时数据;
int totalBytes=data.Length;
int currentBytes=0;
int bufferLength=constChunkSize;
byte[]sendBytes=新字节[constChunkSize];
while(currentBytes
为什么要使用
BeginSend
+
睡眠
?这是a:不安全(你不知道它是在20毫秒后完成的),b:可能会太慢(它可能会更快完成)。如果您不想使用异步API,那么:不要-只使用
Send
。。。?实际上,如果您使用的是
BeginSend
,则需要调用
EndSend
,以捕获任何异常,并确保不会泄漏。我确实调用EndSend。我睡觉的原因是,如果我不睡觉,它只会丢失数据包。由于某些原因,如果你发送数据包真的很快,它只会丢弃大部分数据包,甚至是通过局域网。我很抱歉没有打电话给EndSend-但是,仍然存在时间问题;在调用EndSend之后,应该在回调中调用下一个BeginSend。也许这样做可以让你消除睡眠,这应该可以解决性能问题。我不确定问题出在哪里,但我最终让它与TCP一起工作。线程如下:将块大小增加到MTU(1500个字符)以上可能会使情况变得更糟,因为数据包将不得不被分割,任何片段的丢失都将导致整个数据包的丢失。当然,如果你在每个包之间睡觉,它会慢得多。onDataReceive做什么?更好的做法是在接收线程中尽可能少地处理数据包,并将数据包分派给工作线程。到那时你就可以摆脱睡眠(20)