UDP - Могу ли я отправить две части дейтаграммы и заставить принимающую сторону объединить их в одну? - PullRequest
5 голосов
/ 30 июня 2011

Это, возможно, глупый вопрос, но поскольку я относительно новичок в UDP, то здесь все идет ... Если у меня есть два отдельных байтовых массива, мне нужно, чтобы принимающая сторона получала как один большой массив, например:

byte[] Array1 = {1,1,1}
byte[] Array2 = {2,2,2}

Можно ли избежать создания буфера и скопировать в него каждый массив, а затем отправить этот буфер, например так:

byte[] Buffer= new byte[Array1.Length + Array2.Length];
Buffer.BlockCopy(Array1, 0, Buffer, 0, Array1.Length);
Buffer.BlockCopy(Array2, 0, Buffer, Array1.Length, Array2.Length);

udpClient.Send(Buffer, Buffer.Length);

Потому что, если они большие и скорость передачи данных высока, копирование потребляет много системных ресурсов ... Так что я могу как-то сказать udpClient, что я запускаю фрагментацию UDP, а затем сделать так:

udpClient.ImStartingOneBigDatagram();

udpClient.Send(Array1, Array1.Length);
udpClient.Send(Array2, Array2.Length);

udpClient.ThatsAllFolks();

И будьте уверены, что получающая сторона получит:

byte[] recv = {1,1,1,2,2,2}

Я использую C # для этого, и мне не нужно использовать UdpClient, я просто высказывал свою точку зрения.

Ответы [ 2 ]

2 голосов
/ 01 июля 2011

Использовать эквивалент Win32 API WSASendMsg:

public int Send(
    IList<ArraySegment<byte>> buffers,
    SocketFlags socketFlags,
    out SocketError errorCode
)

http://msdn.microsoft.com/en-us/library/ms145161.aspx

Но в конечном итоге это преждевременная оптимизация. Если вы проведете какое-то тестирование, то увидите, что для использования массивов сбора данных ввода-вывода вам потребуется не менее 9 КБ данных для повышения производительности. Для небольших буферов, то есть меньше, чем размер страницы (4 КБ на x86), быстрее создать смежный буфер самостоятельно, прежде чем переходить к API сокетов.

2 голосов
/ 30 июня 2011

Да, вы можете разбить любой блок данных на две части и отправить его в виде двух отдельных пакетов UDP.Однако UDP не гарантирует доставку, поэтому одна из частей может пропасть при транспортировке.Что вы будете делать, если получатель получит только половину сообщения?Выбросьте это, очевидно, но что-то, что нужно иметь в виду с UDP.

Итак, чтобы ответить на последнюю часть вашего вопроса «И будьте уверены, что получающая сторона получит ...», ответ - нет.Вы используете UDP, поэтому вы не можете быть уверены, что получающая сторона получит что-либо.

Если вы хотите разбить отправку на несколько частей для вашего удобства, а не из-за размера сетевого пакета, выможет, конечно, написать свой собственный класс-оболочку, который расположен над UDP-клиентом и принимает несколько фрагментов данных с помощью вызова метода Send и отправляет все данные в udpclient.Send () только при вызове .ThatsAllFolks в вашем классе-оболочке.Но это не приведет к сокращению накладных расходов памяти, поскольку оболочка должна накапливать данные в памяти перед отправкой Big Send.Эта обертка будет просто косметическим удобством для вашего клиентского кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...