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

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

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

Привет, есть один код асинхронного сервера, взял отсюда http://msdn.microsoft.com/ru-ru/library/dd335942.aspx#Section6 вот его код
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Net.NetworkInformation;
  7. using System.Net;
  8. using System.Threading;
  9. using System.Net.Sockets;
  10. namespace ConsoleApplication3
  11. {
  12. class Program
  13. {
  14. class ThreadedServer
  15. {
  16. private Socket _serverSocket;
  17. private int _port;
  18. public ThreadedServer(int port) { _port = port; }
  19.  
  20. public void Start()
  21. {
  22. SetupServerSocket();
  23. for (int i = 0; i < 10; i++)
  24. _serverSocket.BeginAccept(new
  25. AsyncCallback(AcceptCallback), _serverSocket);
  26. }
  27. private class ConnectionInfo
  28. {
  29. public Socket Socket;
  30. public byte[] Buffer;
  31. }
  32. private List<ConnectionInfo> _connections = new List<ConnectionInfo>();
  33. private void SetupServerSocket()
  34. {
  35. // Получаем информацию о локальном компьютере
  36. /* IPHostEntry localMachineInfo =
  37. Dns.GetHostEntry(Dns.GetHostName());*/
  38. IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, _port);
  39.  
  40. // Создаем сокет, привязываем его к адресу
  41. // и начинаем прослушивание
  42. _serverSocket = new Socket(
  43. myEndpoint.Address.AddressFamily,
  44. SocketType.Stream, ProtocolType.Tcp);
  45. _serverSocket.Bind(myEndpoint);
  46. _serverSocket.Listen((int)
  47. SocketOptionName.MaxConnections);
  48. }
  49. private void AcceptCallback(IAsyncResult result)
  50. {
  51. ConnectionInfo connection = new ConnectionInfo();
  52. try
  53. {
  54. // Завершение операции Accept
  55. Socket s = (Socket)result.AsyncState;
  56. connection.Socket = s.EndAccept(result);
  57. connection.Buffer = new byte[255];
  58. lock (_connections) _connections.Add(connection);
  59. // Начало операции Receive и новой операции Accept
  60. connection.Socket.BeginReceive(connection.Buffer,
  61. 0, connection.Buffer.Length, SocketFlags.None,
  62. new AsyncCallback(ReceiveCallback),
  63. connection);
  64. _serverSocket.BeginAccept(new AsyncCallback(
  65. AcceptCallback), result.AsyncState);
  66. }
  67. catch (SocketException exc)
  68. {
  69. CloseConnection(connection);
  70. Console.WriteLine("Socket exception: " +
  71. exc.SocketErrorCode);
  72. }
  73. catch (Exception exc)
  74. {
  75. CloseConnection(connection);
  76. Console.WriteLine("Exception: " + exc);
  77. }
  78. }
  79. private void ReceiveCallback(IAsyncResult result)
  80. {
  81. ConnectionInfo connection =
  82. (ConnectionInfo)result.AsyncState;
  83. try
  84. {
  85. int bytesRead =
  86. connection.Socket.EndReceive(result);
  87. if (0 != bytesRead)
  88. {
  89. lock (_connections)
  90. {
  91. Console.WriteLine("начало " + Encoding.UTF8.GetString(connection.Buffer, 0, bytesRead) + " конец");
  92. foreach (ConnectionInfo conn in
  93. _connections)
  94. {
  95. if (connection != conn)
  96. {
  97. conn.Socket.Send(connection.Buffer,
  98. bytesRead, SocketFlags.None);
  99. }
  100. }
  101. }
  102. connection.Socket.BeginReceive(
  103. connection.Buffer, 0,
  104. connection.Buffer.Length, SocketFlags.None,
  105. new AsyncCallback(ReceiveCallback),
  106. connection);
  107. }
  108. else CloseConnection(connection);
  109. }
  110. catch (SocketException exc)
  111. {
  112. CloseConnection(connection);
  113. Console.WriteLine("Socket exception: " +
  114. exc.SocketErrorCode);
  115. }
  116. catch (Exception exc)
  117. {
  118. CloseConnection(connection);
  119. Console.WriteLine("Exception: " + exc);
  120. }
  121. }
  122. private void CloseConnection(ConnectionInfo ci)
  123. {
  124. ci.Socket.Close();
  125. lock (_connections) _connections.Remove(ci);
  126. }
  127.  
  128. }
  129.  
  130. static void Main(string[] args)
  131. {
  132. ThreadedServer ts = new ThreadedServer(9393);
  133. ts.Start();
  134. Console.ReadLine();
  135.  
  136. }
  137.  
  138. }
  139. }
Объясните пожалуйста, как работает функция
Листинг программы
  1. private void AcceptCallback(IAsyncResult result)
и для чего в ней этот код
Листинг программы
  1. connection.Socket.BeginReceive(connection.Buffer,
  2. 0, connection.Buffer.Length, SocketFlags.None,
  3. new AsyncCallback(ReceiveCallback),
  4. connection);
  5. _serverSocket.BeginAccept(new AsyncCallback(
  6. AcceptCallback), result.AsyncState);
Это был вопрос по серверу, а вот по клиенту. Сервер то работает, но у меня же клиент не идиот который может делать только что-то одно!! Проблема в том, что для того, чтобы получить что-то от сервера, клиент обязательно должен че-то отправить. А как сделать чтобы задачи отправки и принятия сообщений работали параллельно и не зависели друг от друга. Я-то пробовал как-то модифицировать уже имеющейся у меня код клиента, идея была в том, чтобы запустить операцию принятия сообщений в отдельном потоке, но понятное дело - у меня ничего не вышло. Вот этот смехотворный код
Листинг программы
  1. using System; ///////////////////////////////////////////////////
  2. using System.Collections.Generic;/////// Консольный стандарт //////////
  3. using System.Text; ///////////////////////////////////////////////////
  4. using System.Net.Sockets; ///// Вот он, родимый коллекшн классов //////
  5. using System.Threading;
  6. namespace MyFirstClient
  7. {
  8. class Program
  9. {
  10. public static void Recieve(Object sock)
  11. {
  12. byte[] remdata = { };
  13. Socket s = (Socket)sock;
  14. while (true)
  15. {
  16. try
  17. {
  18. s.Receive(remdata);
  19. Console.WriteLine(Encoding.UTF8.GetString(remdata));
  20. }
  21. catch
  22. {
  23. s.Close();
  24. }
  25. }
  26. }
  27. static void Main(string[] args)
  28. {
  29. string data; // Юзерская дата
  30. byte[] remdata = { }; // Дата с сервака
  31. TcpClient Client = new TcpClient(); // создаем экземпляр
  32. Console.Write("IP to connect to: 127.0.0.1"); // всякая фигня типа UI
  33. string ip = "127.0.0.1";
  34. Console.WriteLine("Port: 777 ");
  35. int port = 9393;
  36. Console.WriteLine("Connecting to server...");
  37. try
  38. {
  39. Client.Connect(ip, port); // попробуем подконнектиться.
  40. } // если не получится - эксепшн
  41. catch
  42. {
  43. Console.WriteLine("Cannot connect to remote host!");
  44. return;
  45. }
  46. Console.Write("done\r\nTo end, type 'END'");
  47. Socket Sock = Client.Client; // нах всякие NetStream'ы
  48. Thread thread = new Thread(Recieve);
  49. thread.Start(Sock);
  50.  
  51. while (true) // базарим с сервером… если достало – пишем END
  52. {
  53. Console.Write("\r\n>");
  54. data = Console.ReadLine();
  55. if (data == "END")
  56. break;
  57. Sock.Send(Encoding.UTF8.GetBytes(data)); // преобразование
  58. Console.WriteLine("ты послал: " + data);
  59. // типов
  60. try
  61. {
  62. Sock.Receive(remdata);
  63. }
  64. catch
  65. {
  66. Console.WriteLine("error");
  67. }
  68. Console.WriteLine("<" + Encoding.UTF8.GetString(remdata));
  69. }
  70. Client.Close();
  71. Console.ReadLine();
  72. }
  73. }
  74. }
комментарии не мои. Помогите, пожалуйста, разобраться с этим всем, умоляю!!!

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

textual
Листинг программы
  1. private static void AcceptCompleted()
  2.         {
  3.             byte[] data = new byte[1024];
  4.          
  5.                 int recv = socket.Receive(data, data.Length, SocketFlags.None); // вот тут исключение
  6.  
  7.  
  8.  
  9.                 if (recv != 0)
  10.                 {
  11.                     string message = Encoding.UTF8.GetString(data, 0, recv);
  12.                     Console.WriteLine(message);
  13.                 }
  14.      
  15.  
  16.         }

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


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

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

10   голосов , оценка 4.2 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы