Асинхронный сервер на 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();
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.769 из 5