Потеря пакетов из-за возникновения очень маловероятной ситуации? - PullRequest
1 голос
/ 07 февраля 2012

В последнее время я довольно много работал с UDP-сокетами. Я читал, что UDP не имеет внутреннего буфера. Это означает, что если пакет прибывает и его никто не ждет, он сбрасывается. Я думал о ситуации, которая случается очень маловероятно. Но если это произойдет, это может вызвать проблемы.

byte[] buffer = new byte[1024];
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(...);
while (true)
{
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
    socket.ReceiveFrom(buffer, ref remote);
    socket.SendTo(remote, new byte[] { 1, 2, 3, 4 });
}

Что если во время выполнения SendTo, который не является асинхронным методом (поэтому он блокирует поток, в котором он запущен, до тех пор, пока он не будет завершен, то есть завершен отправкой данных), поступит другой пакет с другого хоста? Поскольку метод ReceiveFrom не выполняется, будет ли пакет сброшен?

Просто предположив "да", я подумал об использовании асинхронных сокетов. Это будет выглядеть так:

Socket socket;    
byte[] buffer;

void StartServer()
{
    buffer = new byte[1024];
    socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    socket.Bind(...);
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0);

    StartReceive();
}

void StartReceive()
{
    socket.BeginReceiveFrom(buffer, 0, buffer.Size, SocketFlags.None, ref remote, OnReceive, null);
}

void OnReceive(IAsyncState state)
{
    EndPoint epRemote = new IPEndPoint(IPAddress.Any, 0);
    socket.EndReceiveFrom(state, ref epRemote);
    socket.BeginSendTo(new byte[] { 1, 2, 3, 4 }, 0, 4, SocketFlags.None, epRemote, null, null);
    StartReceive();
}

Когда метод OnReceive вызывается функцией socket.BeginReceiveFrom, когда он завершен, выполняется его код. Поскольку этот код использует BeginSendTo, он не блокирует поток. Но что, если пакет приходит до того, как OnReceive сможет вызвать StartReceive? Будет ли это потеряно?

Итак, мой вопрос: Буферизуется ли пакет UDP вообще, и если да, то как долго?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2012

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

2 голосов
/ 07 февраля 2012

Нет, внутренние компоненты платформы будут гарантировать, что пакеты находятся в очереди, пока они не будут проанализированы. Обычно это достигается с помощью буфера, который сохраняет пакеты в течение периода времени, пока получатель фактически не получит пакеты.

Существует несколько уровней, которые обеспечивают это, для получения дополнительной информации, и поскольку вы используете прикладной уровень OSI, вам следует изучить OSI, чтобы глубоко понять эти концепции.

...