Сетевой чат с приватными сообщениями - C#

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

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

Здравствуйте дорогие друзья. Есть вот такой чат, который состоит из сервера и клиента (естественно клиентов может быть много). Сделано все красиво, но нужно его усовершенствовать, а именно нужно сделать так, что бы при входе в чат в checkedListBox выводился список онлайн юзеров. Так же при отправке сообщения можно было выбрать одного или нескольких юзеров которым нужно отправить сообщение. Как это будет проще сделать? Код клиента (C#):
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Net.Sockets;
  11. using System.IO;
  12. using System.Net;
  13. using System.Threading;
  14.  
  15. namespace MyClient
  16. {
  17. public partial class Form1 : Form
  18. {
  19. static private Socket Client;
  20. private IPAddress ip = null;
  21. private int port = 0;
  22. private Thread th;
  23. public Form1()
  24. {
  25. InitializeComponent();
  26. richTextBox1.Enabled = false;
  27. richTextBox2.Enabled = false;
  28. button1.Enabled = false;
  29. try
  30. {
  31. var sr = new StreamReader(@"Client_info/data_info.txt");
  32. string buffer = sr.ReadToEnd();
  33. sr.Close();
  34. string[] connect_info = buffer.Split(':');
  35. ip = IPAddress.Parse(connect_info[0]);
  36. port = int.Parse(connect_info[1]);
  37. label4.ForeColor = Color.Green;
  38. label4.Text = "Настройки: \n IP сервера: " + connect_info[0] + "\n Порт сервера: " + connect_info[1];
  39. }
  40. catch (Exception ex)
  41. {
  42. label4.ForeColor = Color.Red;
  43. label4.Text = "Настройки не найдены";
  44. Form2 form = new Form2();
  45. form.Show();
  46. }
  47. }
  48. private void Form1_Load(object sender, EventArgs e)
  49. {
  50. }
  51. private void настройкиToolStripMenuItem_Click(object sender, EventArgs e)
  52. {
  53. Form2 form = new MyClient.Form2();
  54. form.Show();
  55. }
  56. void SendMessage(string message)
  57. {
  58. if (message != " " && message != "")
  59. {
  60. byte[] buffer = new byte[1024];
  61. buffer = Encoding.UTF8.GetBytes(message);
  62. Client.Send(buffer);
  63. }
  64. }
  65. void RegOfMessage()
  66. {
  67. byte[] buffer = new byte[1224];
  68. for (int i = 0; i < buffer.Length; i++)
  69. {
  70. buffer[i] = 0;
  71. }
  72. for (;;)
  73. {
  74. try
  75. {
  76. Client.Receive(buffer);
  77. string messege = Encoding.UTF8.GetString(buffer);
  78. int count = messege.IndexOf(";;;5");
  79. if (count == -1)
  80. {
  81. continue;
  82. }
  83. string Cleaner_Message = "";
  84. for (int i = 0; i < count; i++)
  85. {
  86. Cleaner_Message += messege[i];
  87. }
  88. for (int i = 0; i < buffer.Length; i++)
  89. {
  90. buffer[i] = 0;
  91. }
  92. this.Invoke((MethodInvoker)delegate ()
  93. {
  94. richTextBox1.AppendText(Cleaner_Message);
  95. });
  96. }
  97. catch (Exception ex) { }
  98. }
  99. }
  100. private void button2_Click(object sender, EventArgs e)
  101. {
  102. if (textBox1.Text != " " && textBox1.Text != "")
  103. {
  104. button1.Enabled = true;
  105. richTextBox2.Enabled = true;
  106. Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  107. if (ip != null)
  108. {
  109. Client.Connect(ip, port);
  110. th = new Thread(delegate () { RegOfMessage(); });
  111. th.Start();
  112. }
  113.  
  114. }
  115. }
  116. private void button1_Click(object sender, EventArgs e)
  117. {
  118. SendMessage("\n" + textBox1.Text + ":" + richTextBox2.Text + ";;;5");
  119. richTextBox2.Clear();
  120. }
  121. private void выходToolStripMenuItem_Click(object sender, EventArgs e)
  122. {
  123. if (th != null) th.Abort();
  124. Application.Exit();
  125. }
  126. private void авторToolStripMenuItem_Click(object sender, EventArgs e)
  127. {
  128. MessageBox.Show("Created by N7 \n In 2015 year");
  129. }
  130. private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
  131. {
  132. }
  133. }
  134. }
Код сервера (C++):
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Threading;
  11. using System.Net.Sockets;
  12. using System.Net;
  13. using System.IO;
  14.  
  15. namespace Client
  16. {
  17. public partial class ChatForm : Form
  18. {
  19. private delegate void ChatEvent(string content,string clr);
  20. private ChatEvent _addMessage;
  21. private Socket _serverSocket;
  22. private Thread listenThread;
  23. private string _host = "127.0.0.1";
  24. private int _port = 2222;
  25. public ChatForm()
  26. {
  27. InitializeComponent();
  28. _addMessage = new ChatEvent(AddMessage);
  29. userMenu = new ContextMenuStrip();
  30. ToolStripMenuItem PrivateMessageItem = new ToolStripMenuItem();
  31. PrivateMessageItem.Text = "Личное сообщение";
  32. PrivateMessageItem.Click += delegate
  33. {
  34. if (userList.SelectedItems.Count > 0)
  35. {
  36. messageData.Text = $""{userList.SelectedItem} ";
  37. }
  38. };
  39. userMenu.Items.Add(PrivateMessageItem);
  40. ToolStripMenuItem SendFileItem = new ToolStripMenuItem()
  41. {
  42. Text = "Отправить файл"
  43. };
  44. SendFileItem.Click += delegate
  45. {
  46. if (userList.SelectedItems.Count == 0)
  47. {
  48. return;
  49. }
  50. OpenFileDialog ofp = new OpenFileDialog();
  51. ofp.ShowDialog();
  52. if (!File.Exists(ofp.FileName))
  53. {
  54. MessageBox.Show($"Файл {ofp.FileName} не найден!");
  55. return;
  56. }
  57. FileInfo fi = new FileInfo(ofp.FileName);
  58. byte[] buffer = File.ReadAllBytes(ofp.FileName);
  59. Send($"#sendfileto|{userList.SelectedItem}|{buffer.Length}|{fi.Name}");//g
  60. Send(buffer);
  61.  
  62. };
  63. userMenu.Items.Add(SendFileItem);
  64. userList.ContextMenuStrip = userMenu;
  65. }
  66. private void AddMessage(string Content,string Color = "Black")
  67. {
  68. if(InvokeRequired)
  69. {
  70. Invoke(_addMessage,Content,Color);
  71. return;
  72. }
  73. chatBox.SelectionStart = chatBox.TextLength;
  74. chatBox.SelectionLength = Content.Length;
  75. chatBox.SelectionColor = getColor(Color);
  76. chatBox.AppendText(Content + Environment.NewLine);
  77. }
  78. private Color getColor(string text)
  79. {
  80. //govno
  81. if (Color.Red.Name.Contains(text))
  82. return Color.Red;
  83. return Color.Black;
  84. }
  85. private void ChatForm_Load(object sender, EventArgs e)
  86. {
  87. IPAddress temp = IPAddress.Parse(_host);
  88. _serverSocket = new Socket(temp.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
  89. _serverSocket.Connect(new IPEndPoint(temp, _port));
  90. if (_serverSocket.Connected)
  91. {
  92. enterChat.Enabled = true;
  93. nicknameData.Enabled = true;
  94. AddMessage("Связь с сервером установлена.");
  95. listenThread = new Thread(listner);
  96. listenThread.IsBackground = true;
  97. listenThread.Start();
  98. }
  99. else
  100. AddMessage("Связь с сервером не установлена.");
  101. }
  102. public void Send(byte[] buffer)
  103. {
  104. try
  105. {
  106. _serverSocket.Send(buffer);
  107. }
  108. catch { }
  109. }
  110. public void Send(string Buffer)
  111. {
  112. try
  113. {
  114. _serverSocket.Send(Encoding.Unicode.GetBytes(Buffer));
  115. }
  116. catch { }
  117. }
  118.  
  119. public void handleCommand(string cmd)
  120. {
  121. string[] commands = cmd.Split('#');
  122. int countCommands = commands.Length;
  123. for (int i = 0; i < countCommands; i++)
  124. {
  125. try
  126. {
  127. string currentCommand = commands[i];
  128. if (string.IsNullOrEmpty(currentCommand))
  129. continue;
  130. if (currentCommand.Contains("setnamesuccess"))
  131. {
  132.  
  133. //Из-за того что программа пыталась получить доступ к контролам из другого потока вылетал эксепщен и поля не разблокировались
  134. Invoke((MethodInvoker)delegate
  135. {
  136. AddMessage($"Добро пожаловать, {nicknameData.Text}");
  137. nameData.Text = nicknameData.Text;
  138. chatBox.Enabled = true;
  139. messageData.Enabled = true;
  140. userList.Enabled = true;
  141. nicknameData.Enabled = false;
  142. enterChat.Enabled = false;
  143. });
  144. continue;
  145. }
  146. if(currentCommand.Contains("setnamefailed"))
  147. {
  148. AddMessage("Неверный ник!");
  149. continue;
  150. }
  151. if(currentCommand.Contains("msg"))
  152. {
  153. string[] Arguments = currentCommand.Split('|');
  154. AddMessage(Arguments[1], Arguments[2]);
  155. continue;
  156. }
  157. if(currentCommand.Contains("userlist"))
  158. {
  159. string[] Users = currentCommand.Split('|')[1].Split(',');
  160. int countUsers = Users.Length;
  161. userList.Invoke((MethodInvoker)delegate { userList.Items.Clear(); });
  162. for(int j = 0;j < countUsers;j++)
  163. {
  164. userList.Invoke((MethodInvoker)delegate { userList.Items.Add(Users[j]) ; });
  165. }
  166. continue;
  167. }
  168. if(currentCommand.Contains("gfile"))
  169. {
  170. string[] Arguments = currentCommand.Split('|');
  171. string fileName = Arguments[1];
  172. string FromName = Arguments[2];
  173. string FileSize = Arguments[3];
  174. string idFile = Arguments[4];
  175. DialogResult Result = MessageBox.Show($"Вы хотите принять файл {fileName} размером {FileSize} от {FromName}","Файл",MessageBoxButtons.YesNo);
  176. if (Result == DialogResult.Yes)
  177. {
  178. Thread.Sleep(1000);
  179. Send("#yy|"+idFile);
  180. byte[] fileBuffer = new byte[int.Parse(FileSize)];
  181. _serverSocket.Receive(fileBuffer);
  182. File.WriteAllBytes(fileName, fileBuffer);
  183. MessageBox.Show($"Файл {fileName} принят.");
  184. }
  185. else
  186. Send("nn");
  187. continue;
  188. }
  189. }
  190. catch (Exception exp) { Console.WriteLine("Error with handleCommand: " + exp.Message); }
  191. }
  192.  
  193. }
  194. public void listner()
  195. {
  196. try
  197. {
  198. while (_serverSocket.Connected)
  199. {
  200. byte[] buffer = new byte[2048];
  201. int bytesReceive = _serverSocket.Receive(buffer);
  202. handleCommand(Encoding.Unicode.GetString(buffer, 0, bytesReceive));
  203. }
  204. }
  205. catch
  206. {
  207. MessageBox.Show("Связь с сервером прервана");
  208. Application.Exit();
  209. }
  210. }
  211. private void enterChat_Click(object sender, EventArgs e)
  212. {
  213. string nickName = nicknameData.Text;
  214. if (string.IsNullOrEmpty(nickName))
  215. return;
  216. Send($"#setname|{nickName}");
  217. }
  218. private void ChatForm_FormClosing(object sender, FormClosingEventArgs e)
  219. {
  220. if (_serverSocket.Connected)
  221. Send("#endsession");
  222. }
  223. private void messageData_KeyUp(object sender, KeyEventArgs e)
  224. {
  225. if(e.KeyData == Keys.Enter)
  226. {
  227. string msgData = messageData.Text;
  228. if (string.IsNullOrEmpty(msgData))
  229. return;
  230. if(msgData[0] == '"')
  231. {
  232. string temp = msgData.Split(' ')[0];
  233. string content = msgData.Substring(temp.Length+1);
  234. temp = temp.Replace(""", string.Empty);
  235. Send($"#private|{temp}|{content}");
  236. }
  237. else
  238. Send($"#message|{msgData}");
  239. messageData.Text = string.Empty;
  240. }
  241. }
  242. }
  243. }

Решение задачи: «Сетевой чат с приватными сообщениями»

textual
Листинг программы
  1. #pragma comment(lib,"Ws2_32.lib")
  2. #include <WinSock2.h>
  3. #include <iostream>
  4. #include <WS2tcpip.h>
  5.  
  6. SOCKET Connect;
  7. SOCKET* Connections;
  8. SOCKET Listen;
  9.  
  10.  
  11. int ClientCount = 0;
  12.  
  13. void SendMessageToClient(int ID)
  14. {
  15.     char* buffer = new char[1024];
  16.     for (;; Sleep(75))
  17.     {
  18.         memset(buffer, 0, sizeof(buffer));
  19.         if (recv(Connections[ID], buffer, 1024, NULL))
  20.         {
  21.             printf(buffer);
  22.             printf("/n");
  23.             for (int i = 0; i <= ClientCount; i++)
  24.             {
  25.                 send(Connections[i], buffer, strlen(buffer), NULL);
  26.             }
  27.         }
  28.     }
  29.     delete buffer;
  30. }
  31. int main()
  32. {
  33.     setlocale(LC_ALL, "russian");
  34.     WSAData data;
  35.     WORD version = MAKEWORD(2, 2);
  36.     int res = WSAStartup(version, &data);
  37.     if (res != 0)
  38.     {
  39.         return 0;
  40.     }
  41.  
  42.     struct addrinfo hints;
  43.     struct addrinfo * result;
  44.  
  45.  
  46.     Connections = (SOCKET*)calloc(64, sizeof(SOCKET));
  47.  
  48.     ZeroMemory(&hints, sizeof(hints));
  49.  
  50.     hints.ai_family = AF_INET;
  51.     hints.ai_flags = AI_PASSIVE;
  52.     hints.ai_socktype = SOCK_STREAM;
  53.     hints.ai_protocol = IPPROTO_TCP;
  54.  
  55.     getaddrinfo(NULL, "7770", &hints, &result);
  56.     Listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  57.     bind(Listen, result->ai_addr, result->ai_addrlen);
  58.     listen(Listen, SOMAXCONN);
  59.  
  60.     freeaddrinfo(result);
  61.  
  62.     printf("Server connect...");
  63.     char m_connetc[] = "Connect...;;;5";
  64.     for (;; Sleep(75))
  65.     {
  66.         if (Connect = accept(Listen, NULL, NULL))
  67.         {
  68.             printf("Client connect.../n");
  69.             Connections[ClientCount] = Connect;
  70.             send(Connections[ClientCount], m_connetc, strlen(m_connetc), NULL);
  71.             ClientCount++;
  72.             CreateThread(NULL, NULL, (PTHREAD_START_ROUTINE)SendMessageToClient, (LPVOID)(ClientCount - 1), NULL, NULL);
  73.         }
  74.  
  75.     }
  76.     return 1;
  77. }

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


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

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

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

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

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

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