Как работает метод Socket.BeginAccept - C#
Формулировка задачи:
Пожалуйста объясните "на пальцах" как работают некоторые функции в этом коде. Вопросы указаны в комментариях.
Описанный ниже код принадлежит серверу, к которому обращаются клиенты с просьбой выслать им текущее время.
Основная цель для меня научиться делать многопоточные серверы с помощью асинхронного обратного вызова.
Не обидьте школьника, помогите советом.
Пока это все вопросы. Пожалуйста помогите разобраться. Надеюсь ваши ответы помогут мне постичь истину)
Если можно, объясните структуру и алгоритм работы метода socket.BeginAccept() своими словами или на простом примере, а не цитатами из msdn с корявым переводом.
Код взят отсюда
namespace Multi_Server { class Program { private static Socket _serverSocket; private static readonly List<Socket> _clientSockets = new List<Socket>(); //1) для чего нужен этот список сокетов?? private const int _BUFFER_SIZE = 2048; private const int _PORT = 100; private static readonly byte[] _buffer = new byte[_BUFFER_SIZE]; static void Main() { Console.Title = "Server"; SetupServer(); Console.ReadLine(); CloseAllSockets(); } private static void SetupServer() { Console.WriteLine("Setting up server..."); _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _serverSocket.Bind(new IPEndPoint(IPAddress.Any, _PORT)); _serverSocket.Listen(5); _serverSocket.BeginAccept(AcceptCallback, null); //2) AcceptCallback, это насколько я понял функция которая будет вызвана когда кто либо постучится в наш порт. А что здесь есть NULL?? Console.WriteLine("Server setup complete"); } /// Close all connected client (we do not need to shutdown the server socket as its connections /// are already closed with the clients) private static void CloseAllSockets() { foreach (Socket socket in _clientSockets) { socket.Shutdown(SocketShutdown.Both); socket.Close(); } _serverSocket.Close(); } private static void AcceptCallback(IAsyncResult AR) //3) Это та самая функция которая вызывается через Socket.BeginAccept (?). Какую роль здесь играет IAsyncResult? { Socket socket; //4) Это открывают отдельный сокет для свежеподключившегося клиента? try { socket = _serverSocket.EndAccept(AR); //5) Что происходит в этой строке? (Та что сверху) } catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets) { return; } _clientSockets.Add(socket); socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket); //6 ReceiveCallback, это функция которая будет вызвана после завершения BeginReceive, а какие данные будет содержать socket? Console.WriteLine("Client connected, waiting for request..."); _serverSocket.BeginAccept(AcceptCallback, null); //7 зачем здесь снова вызывается BeginAccept если обмен данными еще не закончен? } private static void ReceiveCallback(IAsyncResult AR) { Socket current = (Socket)AR.AsyncState; //8) Что делает эта строка? (та что сверху) int received; try { received = current.EndReceive(AR); } catch (SocketException) { Console.WriteLine("Client forcefully disconnected"); current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway _clientSockets.Remove(current); return; } byte[] recBuf = new byte[received]; Array.Copy(_buffer, recBuf, received); string text = Encoding.ASCII.GetString(recBuf); Console.WriteLine("Received Text: " + text); if (text.ToLower() == "get time") // Client requested time { Console.WriteLine("Text is a get time request"); byte[] data = Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString()); current.Send(data); Console.WriteLine("Time sent to client"); } else if (text.ToLower() == "exit") // Client wants to exit gracefully { // Always Shutdown before closing current.Shutdown(SocketShutdown.Both); current.Close(); _clientSockets.Remove(current); Console.WriteLine("Client disconnected"); return; } else { Console.WriteLine("Text is an invalid request"); byte[] data = Encoding.ASCII.GetBytes("Invalid request"); current.Send(data); Console.WriteLine("Warning Sent"); } current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current); } } }
https://www.youtube.com/watch?v=xgLRe7QV6QI
Решение задачи: «Как работает метод Socket.BeginAccept»
textual
Листинг программы
Socket current = (Socket)AR.AsyncState;
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д