Клиент-сервер: как сделать чтобы задачи отправки и принятия сообщений работали параллельно - 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);
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д