Асинхронный сервер на UDP-сокетах - C#
Формулировка задачи:
Хай. Я как-то писал асинх. сервер с использованием TCP-протокола и все получилось очень круто, потому что там есть понятие соединения, и когда очередной клиент подключается к серверу, то мы получаем сокет, с помощью которого можем общатся с каждым из клиентов. А как такое сделать используя UDP-протокол? Там же не создается сокет при покдлючении клиентов так как и подключения как такового не существует. Я вот хотел попробовать написать по аналогии к TCP-серверу, но у меня всякие непонятные ошибки вылазили, а потом я еще запутался с этими EndPoint'ами, и в результате получился такой класс
Я хотел сделать, чтобы, когда любой из клиентов отправляет первое сообщение серверу - он заносился бы в массив, который на сервере, а его сообщение отправлялось бы всем остальным клиентам в списке. Что я делаю не так? У меня при каждом сообщении, даже если это сообщения от одного клиента, в список клиентов заносится новый клиент, а сообщение не отправляется ниодному из клиентов в списке.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace udp_server_test
{
public class Server
{
private string host = "127.0.0.1";
private static int portReceive = 9060;
private int portSend = 9061;
private Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private byte[] buffer = new byte[1024];
public List<ClientData> clientDatas = new List<ClientData>();
private static IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, portReceive);
private EndPoint endPoint = (EndPoint) ipEndPoint;
public class ClientData
{
public EndPoint EndPoint;
public Socket Socket;
}
public void Start()
{
socket.Bind(endPoint);
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint,
new AsyncCallback(ReceiveCallback), socket);
}
private void ReceiveCallback(IAsyncResult ar)
{
ClientData data = new ClientData();
data.Socket = socket;
data.EndPoint = endPoint;
if(!clientDatas.Contains(data))
clientDatas.Add(data);
int n = socket.EndReceiveFrom(ar, ref endPoint);
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, n));
if(clientDatas.Count>1)
foreach (var clientData in clientDatas)
{
clientData.Socket.SendTo(buffer, data.EndPoint);
}
data.Socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref data.EndPoint,
new AsyncCallback(ReceiveCallback), socket);
}
}
}Решение задачи: «Асинхронный сервер на UDP-сокетах»
textual
Листинг программы
public class Server
{
private string host = "127.0.0.1";
private static int portReceive = 9060;
private int portSend = 9061;
private Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private byte[] buffer = new byte[1024];
public List<ClientData> clientDatas = new List<ClientData>();
private static IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, portReceive);
private EndPoint endPoint = (EndPoint)ipEndPoint;
public void Start()
{
socket.Bind(endPoint);
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint,new AsyncCallback(ReceiveCallback), socket);
}
private void ReceiveCallback(IAsyncResult ar)
{
ClientData data = new ClientData();
data.Socket = socket;
data.EndPoint = endPoint;
if (!clientDatas.Contains(data))
clientDatas.Add(data);
int n = socket.EndReceiveFrom(ar, ref endPoint);
Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, n));
if (clientDatas.Count > 1)
foreach (var clientData in clientDatas)
{
clientData.Socket.SendTo(buffer, data.EndPoint);
}
data.Socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref data.EndPoint, new AsyncCallback(ReceiveCallback), socket);
}
}
public class ClientData
{
public EndPoint EndPoint;
public Socket Socket;
}
class Program
{
static void Main(string[] args)
{
Server s = new Server();
s.Start();
Console.WriteLine("Press any key, for exit.");
Console.ReadKey();
}
}