Асинхронный сервер, объяснить работу Callback методов - C#
Формулировка задачи:
Прив. ЕОК, есть один код. Взят он с МСДН и является примером асинхронного сервера. Но на том же МСДН не очень ОК пояснили каждое действие.
Вопросы я написал в виде комментариев, так же присутствуют несколько комментариев самого автора. Я-то читал, что функции Callback запускают выполнение чего-то в отдельном потоке, а потом возвращают результат в основной поток. Но я не могу понять, где, в данном коде, начало какой-то операции, и когда мы получаем результат, и что делается в основном потоке, во время обработки асинхронной операции в другом потоке?
Объясните, пожалуйста, кто как может, можно даже с картинками :3 Спасибо!
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.NetworkInformation; using System.Net; using System.Threading; using System.Net.Sockets; namespace ConsoleApplication3 { class Program { class ThreadedServer { private Socket _serverSocket; private int _port; private bool count = false; public ThreadedServer(int port) { _port = port; } public void Start() { SetupServerSocket(); for (int i = 0; i < 10; i++) // зачем нам 10 раз запускать BeginAccept? _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); // что в этой строке делает BeginAccept? } private class ConnectionInfo { public Socket Socket; public byte[] Buffer; } private List<ConnectionInfo> _connections = new List<ConnectionInfo>(); private void SetupServerSocket() { // Получаем информацию о локальном компьютере IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, _port); // Создаем сокет, привязываем его к адресу // и начинаем прослушивание _serverSocket = new Socket( myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _serverSocket.Bind(myEndpoint); _serverSocket.Listen((int) SocketOptionName.MaxConnections); } private void AcceptCallback(IAsyncResult result) // что это за дивный IAsyncResult result, и когда вызывается этот метод (AcceptCallback)? { ConnectionInfo connection = new ConnectionInfo(); try { // Завершение операции Accept //если это завершение, то когда эта операция началась? Console.WriteLine("Подключился чел"); count = true; Socket s = (Socket)result.AsyncState; connection.Socket = s.EndAccept(result); connection.Buffer = new byte[256]; byte[] b = new byte[1]; lock (_connections) _connections.Add(connection); b = BitConverter.GetBytes(count); foreach (ConnectionInfo conn in _connections) { if (connection != conn) { conn.Socket.Send(b, b.Length, SocketFlags.None); } } count = false; // Начало операции Receive и новой операции Accept connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection); //что делает BeginReceive ? _serverSocket.BeginAccept(new AsyncCallback( AcceptCallback), result.AsyncState); //для чего эти строки? мы же писали аналогичное в функции Start } catch (SocketException exc) { CloseConnection(connection); Console.WriteLine("Socket exception: " + exc.SocketErrorCode); } catch (Exception exc) { CloseConnection(connection); Console.WriteLine("Exception: " + exc); } } private void ReceiveCallback(IAsyncResult result) // что за IAsyncResult result ? { ConnectionInfo connection = (ConnectionInfo)result.AsyncState; try { int bytesRead = connection.Socket.EndReceive(result); if (0 != bytesRead) { lock (_connections) { float x, y, z, x_rot, y_rot, z_rot, w_rot; x = BitConverter.ToSingle(connection.Buffer, 0); y = BitConverter.ToSingle(connection.Buffer, 4); z = BitConverter.ToSingle(connection.Buffer, 8); x_rot = BitConverter.ToSingle(connection.Buffer, 12); y_rot = BitConverter.ToSingle(connection.Buffer, 16); z_rot = BitConverter.ToSingle(connection.Buffer, 20); w_rot = BitConverter.ToSingle(connection.Buffer, 24); Console.WriteLine("Position: {0},{1},{2}", x, y, z); Console.WriteLine("Rotation: {0},{1},{2},{3}", x_rot, y_rot, z_rot, w_rot); foreach (ConnectionInfo conn in _connections) { if (connection != conn) { conn.Socket.Send(connection.Buffer, bytesRead, SocketFlags.None); } } } connection.Socket.BeginReceive( connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection); // что делают эти строки? } else CloseConnection(connection); } catch (SocketException exc) { CloseConnection(connection); Console.WriteLine("Socket exception: " + exc.SocketErrorCode); } catch (Exception exc) { CloseConnection(connection); Console.WriteLine("Exception: " + exc); } } private void CloseConnection(ConnectionInfo ci) { ci.Socket.Close(); lock (_connections) _connections.Remove(ci); } } static void Main(string[] args) { ThreadedServer ts = new ThreadedServer(9390); ts.Start(); Console.ReadLine(); } } }
Решение задачи: «Асинхронный сервер, объяснить работу Callback методов»
textual
Листинг программы
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д