Клиент-сервер: как сделать чтобы задачи отправки и принятия сообщений работали параллельно - C#

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

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

Привет, есть один код асинхронного сервера, взял отсюда http://msdn.microsoft.com/ru-ru/library/dd335942.aspx#Section6 вот его код
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;
 
            public ThreadedServer(int port) { _port = port; }

            public void Start()
            {
                SetupServerSocket();
                for (int i = 0; i < 10; i++)
                    _serverSocket.BeginAccept(new
                        AsyncCallback(AcceptCallback), _serverSocket);
            }
 
            private class ConnectionInfo
            {
                public Socket Socket;
                public byte[] Buffer;
            }
            private List<ConnectionInfo> _connections = new List<ConnectionInfo>();
 
            private void SetupServerSocket()
            {
                // Получаем информацию о локальном компьютере
               /* IPHostEntry localMachineInfo =
                    Dns.GetHostEntry(Dns.GetHostName());*/
                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)
    {
        ConnectionInfo connection = new ConnectionInfo();
        try
        {
            // Завершение операции Accept
            Socket s = (Socket)result.AsyncState;
            connection.Socket = s.EndAccept(result);
            connection.Buffer = new byte[255];
            lock (_connections) _connections.Add(connection);
 
            // Начало операции Receive и новой операции Accept
            connection.Socket.BeginReceive(connection.Buffer,
                0, connection.Buffer.Length, SocketFlags.None,
                new AsyncCallback(ReceiveCallback),
                connection);
            _serverSocket.BeginAccept(new AsyncCallback(
                AcceptCallback), result.AsyncState);
        }
        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)
    {
        ConnectionInfo connection =
            (ConnectionInfo)result.AsyncState;
        try
        {
            int bytesRead =
                connection.Socket.EndReceive(result);
            if (0 != bytesRead)
            {
                lock (_connections)
                {
                    Console.WriteLine("начало " + Encoding.UTF8.GetString(connection.Buffer, 0, bytesRead) + " конец");
                    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(9393);
   
            ts.Start();
            Console.ReadLine();

        }

    }
}
Объясните пожалуйста, как работает функция
private void AcceptCallback(IAsyncResult result)
и для чего в ней этот код
connection.Socket.BeginReceive(connection.Buffer,
                0, connection.Buffer.Length, SocketFlags.None,
                new AsyncCallback(ReceiveCallback),
                connection);
            _serverSocket.BeginAccept(new AsyncCallback(
                AcceptCallback), result.AsyncState);
Это был вопрос по серверу, а вот по клиенту. Сервер то работает, но у меня же клиент не идиот который может делать только что-то одно!! Проблема в том, что для того, чтобы получить что-то от сервера, клиент обязательно должен че-то отправить. А как сделать чтобы задачи отправки и принятия сообщений работали параллельно и не зависели друг от друга. Я-то пробовал как-то модифицировать уже имеющейся у меня код клиента, идея была в том, чтобы запустить операцию принятия сообщений в отдельном потоке, но понятное дело - у меня ничего не вышло. Вот этот смехотворный код
using System;       ///////////////////////////////////////////////////
using System.Collections.Generic;/////// Консольный стандарт //////////
using System.Text;  ///////////////////////////////////////////////////
using System.Net.Sockets; ///// Вот он, родимый коллекшн классов //////
using System.Threading;
 
namespace MyFirstClient
{
    class Program
    {
        public static void Recieve(Object sock)
        {
            byte[] remdata = { };
            Socket s = (Socket)sock;
            while (true)
            {
                try
                {
                    s.Receive(remdata);
                    Console.WriteLine(Encoding.UTF8.GetString(remdata));
                }
                catch
                {
                    s.Close();
                }
            }
           
        }
        static void Main(string[] args)
        {
            string data; // Юзерская дата
            byte[] remdata = { }; // Дата с сервака
            TcpClient Client = new TcpClient(); // создаем экземпляр
            Console.Write("IP to connect to: 127.0.0.1"); // всякая фигня типа UI
            string ip = "127.0.0.1";
            Console.WriteLine("Port: 777 ");
            int port = 9393;
            Console.WriteLine("Connecting to server...");
            try
            {
                Client.Connect(ip, port); // попробуем подконнектиться.
            } // если не получится - эксепшн
            catch
            {
                Console.WriteLine("Cannot connect to remote host!");
                return;
            }
            Console.Write("done\r\nTo end, type 'END'");
            Socket Sock = Client.Client; // нах всякие NetStream'ы
            Thread thread = new Thread(Recieve);
            thread.Start(Sock);

            while (true) // базарим с сервером… если достало – пишем END
            {
                Console.Write("\r\n>");
                data = Console.ReadLine();
                if (data == "END")
                    break;
                Sock.Send(Encoding.UTF8.GetBytes(data)); // преобразование
                Console.WriteLine("ты послал: " + data);
                // типов
                try
                {
                    Sock.Receive(remdata);
                }
                catch
                {
                    Console.WriteLine("error");
                }
                Console.WriteLine("<" + Encoding.UTF8.GetString(remdata));
           
            }
         
            Client.Close();
            Console.ReadLine();
        }
    }
}
комментарии не мои. Помогите, пожалуйста, разобраться с этим всем, умоляю!!!

Решение задачи: «Клиент-сервер: как сделать чтобы задачи отправки и принятия сообщений работали параллельно»

textual
Листинг программы
private static void AcceptCompleted()
        {
            byte[] data = new byte[1024];
          
                int recv = socket.Receive(data, data.Length, SocketFlags.None); // вот тут исключение
 
 
 
                if (recv != 0)
                {
                    string message = Encoding.UTF8.GetString(data, 0, recv);
                    Console.WriteLine(message);
                }
      
 
        }

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


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

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

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