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

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

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

Здравствуйте дорогие друзья. Есть вот такой чат, который состоит из сервера и клиента (естественно клиентов может быть много). Сделано все красиво, но нужно его усовершенствовать, а именно нужно сделать так, что бы при входе в чат в checkedListBox выводился список онлайн юзеров. Так же при отправке сообщения можно было выбрать одного или нескольких юзеров которым нужно отправить сообщение. Как это будет проще сделать? Код клиента (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)
        {
 
        }
    }
}
Код сервера (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.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;
}

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


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

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

15   голосов , оценка 3.867 из 5
Похожие ответы