В настоящее время я пишу прототип приложения на C # /. Net4, где мне нужно передать неизвестное количество данных. Данные считываются из текстового файла и затем сериализуются в байтовый массив.
Теперь мне нужно реализовать оба способа передачи, UDP и TCP. Передача в обоих направлениях работает нормально, но у меня есть некоторые проблемы с UDP. Я предполагаю, что передача с использованием UDP должна быть намного быстрее, чем с использованием TCP, но на самом деле мои тесты показали, что передача UDP примерно в 7-8 раз медленнее, чем с использованием TCP.
Я протестировал передачу с 12-мегабайтным файлом, и передача TCP заняла около 1 секунды, тогда как передача UDP заняла около 7 секунд.
В приложении я использую простые сокеты для передачи данных. Поскольку протокол UDP допускает максимум 65535 КБ на сообщение, я разделил сериализованный байтовый массив файла на несколько частей, каждая из которых имеет размер socker SendBufferSize, а затем я передаю каждую часть с помощью вызова метода Socket.Send ().
Вот код для части отправителя.
while (startOffset < data.Length)
{
if ((startOffset + payloadSize) > data.Length)
{
payloadSize = data.Length - startOffset;
}
byte[] subMessageBytes = new byte[payloadSize + 16];
byte[] messagePrefix = new UdpMessagePrefix(data.Length, payloadSize, messageCount, messageId).ToByteArray();
Buffer.BlockCopy(messagePrefix, 0, subMessageBytes, 0, 16);
Buffer.BlockCopy(data, startOffset, subMessageBytes, messageOffset, payloadSize);
messageId++;
startOffset += payloadSize;
udpClient.Send(subMessageBytes, subMessageBytes.Length);
messages.Add(subMessageBytes);
}
Этот код просто копирует следующую часть для отправки в байтовый массив и затем вызывает метод send для сокета. Моим первым предположением было то, что разделение / копирование байтовых массивов замедляло производительность, но я изолировал и протестировал код разделения, и разделение заняло всего несколько миллисекунд, так что это не вызывало проблему.
int receivedMessageCount = 1;
Dictionary<int, byte[]> receivedMessages = new Dictionary<int, byte[]>();
while (receivedMessageCount != totalMessageCount)
{
byte[] data = udpClient.Receive(ref remoteIpEndPoint);
UdpMessagePrefix p = UdpMessagePrefix.FromByteArray(data);
receivedMessages.Add(p.MessageId, data);
//Console.WriteLine("Received packet: " + receivedMessageCount + " (ID: " + p.MessageId + ")");
receivedMessageCount++;
//Console.WriteLine("ReceivedMessageCount: " + receivedMessageCount);
}
Console.WriteLine("Done...");
return receivedMessages;
Это код на стороне сервера, где я получаю сообщения UDP. Каждое сообщение имеет несколько байтов в качестве префикса, где хранится общее количество сообщений и их размер. Поэтому я просто вызываю socket.Receive в цикле, пока не получу количество сообщений, указанных в префиксе.
Мое предположение здесь состоит в том, что я, возможно, реализовал код передачи UDP недостаточно «эффективно» ... Возможно, один из вас, ребята, уже видит проблему в фрагментах кода, или у меня есть какие-либо другие предложения или подсказки для меня, почему моя передача UDP медленнее, чем TCP.
спасибо заранее!