В последнее время я довольно много работал с 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 вообще, и если да, то как долго?