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