Как работает метод 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;