Асинхронный сервер, объяснить работу Callback методов - C#

Узнай цену своей работы

Формулировка задачи:

Прив. ЕОК, есть один код. Взят он с МСДН и является примером асинхронного сервера. Но на том же МСДН не очень ОК пояснили каждое действие.
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 запускают выполнение чего-то в отдельном потоке, а потом возвращают результат в основной поток. Но я не могу понять, где, в данном коде, начало какой-то операции, и когда мы получаем результат, и что делается в основном потоке, во время обработки асинхронной операции в другом потоке? Объясните, пожалуйста, кто как может, можно даже с картинками :3 Спасибо!

Решение задачи: «Асинхронный сервер, объяснить работу Callback методов»

textual
Листинг программы
_serverSocket.BeginAccept(new
                        AsyncCallback(AcceptCallback), _serverSocket);

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


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

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

7   голосов , оценка 4 из 5
Похожие ответы