Сетевой чат с приватными сообщениями - C#
Формулировка задачи:
Здравствуйте дорогие друзья. Есть вот такой чат, который состоит из сервера и клиента (естественно клиентов может быть много). Сделано все красиво, но нужно его усовершенствовать, а именно нужно сделать так, что бы при входе в чат в checkedListBox выводился список онлайн юзеров. Так же при отправке сообщения можно было выбрать одного или нескольких юзеров которым нужно отправить сообщение. Как это будет проще сделать?
Код клиента (C#):
Код сервера (C++):
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; using System.IO; using System.Net; using System.Threading; namespace MyClient { public partial class Form1 : Form { static private Socket Client; private IPAddress ip = null; private int port = 0; private Thread th; public Form1() { InitializeComponent(); richTextBox1.Enabled = false; richTextBox2.Enabled = false; button1.Enabled = false; try { var sr = new StreamReader(@"Client_info/data_info.txt"); string buffer = sr.ReadToEnd(); sr.Close(); string[] connect_info = buffer.Split(':'); ip = IPAddress.Parse(connect_info[0]); port = int.Parse(connect_info[1]); label4.ForeColor = Color.Green; label4.Text = "Настройки: \n IP сервера: " + connect_info[0] + "\n Порт сервера: " + connect_info[1]; } catch (Exception ex) { label4.ForeColor = Color.Red; label4.Text = "Настройки не найдены"; Form2 form = new Form2(); form.Show(); } } private void Form1_Load(object sender, EventArgs e) { } private void настройкиToolStripMenuItem_Click(object sender, EventArgs e) { Form2 form = new MyClient.Form2(); form.Show(); } void SendMessage(string message) { if (message != " " && message != "") { byte[] buffer = new byte[1024]; buffer = Encoding.UTF8.GetBytes(message); Client.Send(buffer); } } void RegOfMessage() { byte[] buffer = new byte[1224]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } for (;;) { try { Client.Receive(buffer); string messege = Encoding.UTF8.GetString(buffer); int count = messege.IndexOf(";;;5"); if (count == -1) { continue; } string Cleaner_Message = ""; for (int i = 0; i < count; i++) { Cleaner_Message += messege[i]; } for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } this.Invoke((MethodInvoker)delegate () { richTextBox1.AppendText(Cleaner_Message); }); } catch (Exception ex) { } } } private void button2_Click(object sender, EventArgs e) { if (textBox1.Text != " " && textBox1.Text != "") { button1.Enabled = true; richTextBox2.Enabled = true; Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (ip != null) { Client.Connect(ip, port); th = new Thread(delegate () { RegOfMessage(); }); th.Start(); } } } private void button1_Click(object sender, EventArgs e) { SendMessage("\n" + textBox1.Text + ":" + richTextBox2.Text + ";;;5"); richTextBox2.Clear(); } private void выходToolStripMenuItem_Click(object sender, EventArgs e) { if (th != null) th.Abort(); Application.Exit(); } private void авторToolStripMenuItem_Click(object sender, EventArgs e) { MessageBox.Show("Created by N7 \n In 2015 year"); } private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) { } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.Net.Sockets; using System.Net; using System.IO; namespace Client { public partial class ChatForm : Form { private delegate void ChatEvent(string content,string clr); private ChatEvent _addMessage; private Socket _serverSocket; private Thread listenThread; private string _host = "127.0.0.1"; private int _port = 2222; public ChatForm() { InitializeComponent(); _addMessage = new ChatEvent(AddMessage); userMenu = new ContextMenuStrip(); ToolStripMenuItem PrivateMessageItem = new ToolStripMenuItem(); PrivateMessageItem.Text = "Личное сообщение"; PrivateMessageItem.Click += delegate { if (userList.SelectedItems.Count > 0) { messageData.Text = $""{userList.SelectedItem} "; } }; userMenu.Items.Add(PrivateMessageItem); ToolStripMenuItem SendFileItem = new ToolStripMenuItem() { Text = "Отправить файл" }; SendFileItem.Click += delegate { if (userList.SelectedItems.Count == 0) { return; } OpenFileDialog ofp = new OpenFileDialog(); ofp.ShowDialog(); if (!File.Exists(ofp.FileName)) { MessageBox.Show($"Файл {ofp.FileName} не найден!"); return; } FileInfo fi = new FileInfo(ofp.FileName); byte[] buffer = File.ReadAllBytes(ofp.FileName); Send($"#sendfileto|{userList.SelectedItem}|{buffer.Length}|{fi.Name}");//g Send(buffer); }; userMenu.Items.Add(SendFileItem); userList.ContextMenuStrip = userMenu; } private void AddMessage(string Content,string Color = "Black") { if(InvokeRequired) { Invoke(_addMessage,Content,Color); return; } chatBox.SelectionStart = chatBox.TextLength; chatBox.SelectionLength = Content.Length; chatBox.SelectionColor = getColor(Color); chatBox.AppendText(Content + Environment.NewLine); } private Color getColor(string text) { //govno if (Color.Red.Name.Contains(text)) return Color.Red; return Color.Black; } private void ChatForm_Load(object sender, EventArgs e) { IPAddress temp = IPAddress.Parse(_host); _serverSocket = new Socket(temp.AddressFamily,SocketType.Stream,ProtocolType.Tcp); _serverSocket.Connect(new IPEndPoint(temp, _port)); if (_serverSocket.Connected) { enterChat.Enabled = true; nicknameData.Enabled = true; AddMessage("Связь с сервером установлена."); listenThread = new Thread(listner); listenThread.IsBackground = true; listenThread.Start(); } else AddMessage("Связь с сервером не установлена."); } public void Send(byte[] buffer) { try { _serverSocket.Send(buffer); } catch { } } public void Send(string Buffer) { try { _serverSocket.Send(Encoding.Unicode.GetBytes(Buffer)); } catch { } } public void handleCommand(string cmd) { string[] commands = cmd.Split('#'); int countCommands = commands.Length; for (int i = 0; i < countCommands; i++) { try { string currentCommand = commands[i]; if (string.IsNullOrEmpty(currentCommand)) continue; if (currentCommand.Contains("setnamesuccess")) { //Из-за того что программа пыталась получить доступ к контролам из другого потока вылетал эксепщен и поля не разблокировались Invoke((MethodInvoker)delegate { AddMessage($"Добро пожаловать, {nicknameData.Text}"); nameData.Text = nicknameData.Text; chatBox.Enabled = true; messageData.Enabled = true; userList.Enabled = true; nicknameData.Enabled = false; enterChat.Enabled = false; }); continue; } if(currentCommand.Contains("setnamefailed")) { AddMessage("Неверный ник!"); continue; } if(currentCommand.Contains("msg")) { string[] Arguments = currentCommand.Split('|'); AddMessage(Arguments[1], Arguments[2]); continue; } if(currentCommand.Contains("userlist")) { string[] Users = currentCommand.Split('|')[1].Split(','); int countUsers = Users.Length; userList.Invoke((MethodInvoker)delegate { userList.Items.Clear(); }); for(int j = 0;j < countUsers;j++) { userList.Invoke((MethodInvoker)delegate { userList.Items.Add(Users[j]) ; }); } continue; } if(currentCommand.Contains("gfile")) { string[] Arguments = currentCommand.Split('|'); string fileName = Arguments[1]; string FromName = Arguments[2]; string FileSize = Arguments[3]; string idFile = Arguments[4]; DialogResult Result = MessageBox.Show($"Вы хотите принять файл {fileName} размером {FileSize} от {FromName}","Файл",MessageBoxButtons.YesNo); if (Result == DialogResult.Yes) { Thread.Sleep(1000); Send("#yy|"+idFile); byte[] fileBuffer = new byte[int.Parse(FileSize)]; _serverSocket.Receive(fileBuffer); File.WriteAllBytes(fileName, fileBuffer); MessageBox.Show($"Файл {fileName} принят."); } else Send("nn"); continue; } } catch (Exception exp) { Console.WriteLine("Error with handleCommand: " + exp.Message); } } } public void listner() { try { while (_serverSocket.Connected) { byte[] buffer = new byte[2048]; int bytesReceive = _serverSocket.Receive(buffer); handleCommand(Encoding.Unicode.GetString(buffer, 0, bytesReceive)); } } catch { MessageBox.Show("Связь с сервером прервана"); Application.Exit(); } } private void enterChat_Click(object sender, EventArgs e) { string nickName = nicknameData.Text; if (string.IsNullOrEmpty(nickName)) return; Send($"#setname|{nickName}"); } private void ChatForm_FormClosing(object sender, FormClosingEventArgs e) { if (_serverSocket.Connected) Send("#endsession"); } private void messageData_KeyUp(object sender, KeyEventArgs e) { if(e.KeyData == Keys.Enter) { string msgData = messageData.Text; if (string.IsNullOrEmpty(msgData)) return; if(msgData[0] == '"') { string temp = msgData.Split(' ')[0]; string content = msgData.Substring(temp.Length+1); temp = temp.Replace(""", string.Empty); Send($"#private|{temp}|{content}"); } else Send($"#message|{msgData}"); messageData.Text = string.Empty; } } } }
Решение задачи: «Сетевой чат с приватными сообщениями»
textual
Листинг программы
#pragma comment(lib,"Ws2_32.lib") #include <WinSock2.h> #include <iostream> #include <WS2tcpip.h> SOCKET Connect; SOCKET* Connections; SOCKET Listen; int ClientCount = 0; void SendMessageToClient(int ID) { char* buffer = new char[1024]; for (;; Sleep(75)) { memset(buffer, 0, sizeof(buffer)); if (recv(Connections[ID], buffer, 1024, NULL)) { printf(buffer); printf("/n"); for (int i = 0; i <= ClientCount; i++) { send(Connections[i], buffer, strlen(buffer), NULL); } } } delete buffer; } int main() { setlocale(LC_ALL, "russian"); WSAData data; WORD version = MAKEWORD(2, 2); int res = WSAStartup(version, &data); if (res != 0) { return 0; } struct addrinfo hints; struct addrinfo * result; Connections = (SOCKET*)calloc(64, sizeof(SOCKET)); ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; getaddrinfo(NULL, "7770", &hints, &result); Listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol); bind(Listen, result->ai_addr, result->ai_addrlen); listen(Listen, SOMAXCONN); freeaddrinfo(result); printf("Server connect..."); char m_connetc[] = "Connect...;;;5"; for (;; Sleep(75)) { if (Connect = accept(Listen, NULL, NULL)) { printf("Client connect.../n"); Connections[ClientCount] = Connect; send(Connections[ClientCount], m_connetc, strlen(m_connetc), NULL); ClientCount++; CreateThread(NULL, NULL, (PTHREAD_START_ROUTINE)SendMessageToClient, (LPVOID)(ClientCount - 1), NULL, NULL); } } return 1; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д