Асинхронный сервер - чат, много сообщений - C#

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

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

вобщем сделал некое подобие чата, все вроде бы хорошо - отсылает/принимает сообщения нормально от множества клиентов придумал некую эмуляцию большой нагрузки
Листинг программы
  1. for (int i = 0; i < 100; ++i)
  2. {
  3. client.Send("test message " + i);
  4. //Thread.Sleep(150);
  5. }
в итоге сообщения сливаются в строки типа "test message 1test message 2test message 3" и т.д если включить Sleep и пробовать на 2 разных компах в сети глюк остается, но через 127.0.0.1 глюка нет а если без задержки то даже через 127.0.0.1 сливаются серверная часть часть выглядит так
Листинг программы
  1. class AsyncServer
  2. {
  3. int port = 5691;
  4. object locker = new object();
  5. //IPHostEntry host;
  6. IPAddress addr;
  7. Socket _mainSocket;
  8. List<User> connections = new List<User>();
  9. public AsyncServer()
  10. {
  11. //host = Dns.GetHostEntry(Dns.GetHostName());
  12. //foreach (var v in host.AddressList)
  13. // Console.WriteLine(v);
  14. addr = IPAddress.Loopback;//host.AddressList[3];
  15. SetServer();
  16. StartAsync();
  17. }
  18. private void SetServer()
  19. {
  20. _mainSocket = new Socket(addr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  21. _mainSocket.Bind(new IPEndPoint(addr, port));
  22. _mainSocket.Listen(10);
  23. Console.WriteLine("сервер запущен на {0}", _mainSocket.LocalEndPoint);
  24. }
  25. private void StartAsync()
  26. {
  27. for (int i = 0; i < 10; ++i)
  28. _mainSocket.BeginAccept(null, 1024, new AsyncCallback(AcceptCallback), _mainSocket);
  29. }
  30. private void AcceptCallback(IAsyncResult ar)
  31. {
  32. User _user = new User();
  33. _user.Buffer = new byte[256];
  34. try
  35. {
  36. Socket socket = (Socket)ar.AsyncState;
  37. int countBytes = -1;
  38. byte[] buff;
  39. _user.socket = socket.EndAccept(out buff, out countBytes, ar);
  40. if (countBytes > 0)
  41. {
  42. string[] nameAndPass = Encoding.UTF8.GetString(buff, 0, countBytes).Split('&');
  43. _user.uName = nameAndPass[0];
  44. _user.uPassword = nameAndPass[1];
  45. }
  46. //Console.WriteLine("установленно соединение с {0} {1} >> {2}",
  47. // _user.socket.RemoteEndPoint, _user.uName, _user.uPassword);
  48. lock (locker)
  49. connections.Add(_user);
  50. _user.socket.BeginReceive(_user.Buffer, 0, _user.Buffer.Length,
  51. SocketFlags.None, new AsyncCallback(ReceiveCallback), _user);
  52. socket.BeginAccept(null, 1024, new AsyncCallback(AcceptCallback), _mainSocket);
  53. SendSystemMMessage("Вошел в чат", _user);
  54. }
  55. catch (SocketException sExept)
  56. {
  57. Console.WriteLine(sExept.ErrorCode);
  58. }
  59. catch (SystemException ex)
  60. {
  61. Console.WriteLine(ex.Message);
  62. }
  63. }
  64. private void ReceiveCallback(IAsyncResult ar)
  65. {
  66. User user = (User)ar.AsyncState;
  67. try
  68. {
  69. int bytesCount = user.socket.EndReceive(ar);
  70. if (bytesCount != 0)
  71. {
  72. string text = Encoding.UTF8.GetString(user.Buffer, 0, bytesCount);
  73. if (text == "exit")
  74. {
  75. CloseConnect(user);
  76. return;
  77. }
  78. Console.WriteLine(text);
  79. lock (locker)
  80. foreach (User client in connections)
  81. {
  82. client.socket.Send(user.Buffer, 0, bytesCount, SocketFlags.None);
  83. }
  84. user.socket.BeginReceive(user.Buffer, 0, user.Buffer.Length, SocketFlags.None,
  85. new AsyncCallback(ReceiveCallback), user);
  86. }
  87. else CloseConnect(user);
  88. }
  89. catch (SocketException ex)
  90. {
  91. if (ex.ErrorCode == 10054)
  92. {
  93. CloseConnect(user);
  94. SendSystemMMessage("(SocketException) Вышел из чата ", user);
  95. }
  96. }
  97. }
  98. private void CloseConnect(User _user)
  99. {
  100. _user.socket.Close();
  101. lock (locker)
  102. connections.Remove(_user);
  103. SendSystemMMessage("Вышел из чата ", _user);
  104. }
  105. private void SendSystemMMessage(string msg, User from)
  106. {
  107. Console.WriteLine(from.uName + " " + msg);
  108. byte[] tempBuf = Encoding.UTF8.GetBytes(string.Format("{0} " + msg, from.uName));
  109. lock (locker)
  110. foreach (var clinet in connections)
  111. clinet.socket.Send(tempBuf, 0, tempBuf.Length, SocketFlags.None);
  112. }
  113. //private void SendCallback(IAsyncResult ar)
  114. //{
  115. // ((Socket)ar.AsyncState).EndSend(ar);
  116. //}
  117. class User
  118. {
  119. public string uName;
  120. public string uPassword;
  121. public Socket socket;
  122. public byte[] Buffer;
  123. }
  124. }
бьюсь пол дня, чего только не пробовал уже - все равно сообщения сливаются... вот я думаю возможно ли это вообще вылечить? может такой поток сообщений и не должно выдерживать? да и кстати говоря - нормально ли делать такой прием имени юзера и пароля? выглядит как-то не очень надежно...как лучше?

Решение задачи: «Асинхронный сервер - чат, много сообщений»

textual
Листинг программы
  1. while ((bytesRcvd = User.Receive(MessageBuffer, MessageBuffer.Length, SocketFlags.None)) > 0 && User.Connected) {
  2.                     TotalBytes += bytesRcvd;
  3.  
  4.                     Random RND = new Random();//Симулируем лаги
  5.                     int RNDNum = RND.Next(20000000);
  6.                     for (int blabla = 0; blabla < 10000000 + RNDNum; blabla++) {
  7.                         int gg = blabla;
  8.                     }
  9.  
  10.                     Message = Encoding.UTF8.GetString(MessageBuffer, 0, bytesRcvd);
  11.                     //Console.WriteLine(Message + " " + bytesRcvd);
  12.                     String[] MessageArr = Message.Split('\0');
  13.                     foreach (String TM in MessageArr) {
  14.                         if (TM.Length > 0) {
  15.                             Message = TM+"\0";
  16.                             MessageData = Encoding.UTF8.GetBytes(Message);
  17.  
  18.                             Console.WriteLine(Message + " " + Message.Length + " " + bytesRcvd);

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


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

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

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

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

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

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