Мне нужно получить данные по конкретному адресу конечной точки. Но когда я отвечаю на запрос, мне нужно отправить данные с той же конечной точки, на которую были получены данные (в противном случае другая сторона игнорирует их).
Дело в том, что я не хочу обрабатывать запросы последовательно, поэтому один поток получает только данные, чтобы передать их другому потоку, который их обрабатывает и отправляет ответ. AFAIK, один и тот же экземпляр UdpClient не может использоваться одновременно, поэтому единственная идея, которая мне пришла в голову, - создавать новый экземпляр каждый раз, когда я хочу отправить ответ отправителю.
Чтобы добиться того, чего я хочу, я создаю клиента следующим образом ( SocketOptionName.ReuseAddress ):
var udpClient = new UdpClient
{
Client = CreateBoundUdpSocket()
};
public static Socket CreateBoundUdpSocket()
{
var socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
socket.ExclusiveAddressUse = false;
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, optionValue: false);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 1010));
return socket;
}
Дело в том, что UDP-клиенты, используемые для ответа, создаются только для этой отдельной операции и сразу же удаляются. Как я могу быть уверен, что только первый созданный экземпляр будет принимать данные, а не другие? Я не хочу терять пакеты.
Согласно проведенным мною тестам, только первый экземпляр получает что-либо. Даже когда я установил его приемный буфер на 0, никакой другой экземпляр не получает никаких данных. Только когда я закрою первый экземпляр, следующий созданный получит данные. Похоже, что порядок создания был важен, потому что всякий раз, когда я закрываю экземпляр, который в данный момент получает данные, следующий созданный начинает получать его (не случайный, а следующий).
Короче говоря, могу ли я быть уверен, что только первый созданный мной экземпляр будет получать данные?
- РЕДАКТИРОВАТЬ -
Чтобы уточнить мой общий подход (возможно, неверный):
var server = new UdpClient { Client = CreateBoundUdpSocket() };
while (true)
{
IPEndPoint sender = null;
var data = server.Receive(ref sender);
Task.Factory.StartNew
(
(object param) =>
{
// [process the request]
var request = (Tuple<IPEndPoint, byte[]>)param;
// and send a response
using (var client = new UdpClient { Client = CreateBoundUdpSocket() })
{
var someResponse = new byte[] { };
client.Send(someResponse, someResponse.Length, request.Item1);
}
},
state: new Tuple<IPEndPoint, byte[]>(sender, data)
);
}