Сделать мульти-клиентским

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by HacKeRr, 1 Dec 2012.

  1. HacKeRr

    HacKeRr New Member

    Joined:
    8 Mar 2012
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    Всем привет, у меня проблема с асинхронными сокетами. Суть:
    Пишу простенький чат, написал сервер и клиент. С 1 клиентом работает без ошибок. Подключаю ещё 1 клиент и при отправке сообщения мне вылазит ошибка на сервере что "IAsyncResult не был получен" на строке 99. Что я делаю не так?
    Вот код сервера:
    C#
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Drawing;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace Chat
    {
        public partial class Form1 : Form
        {
            Socket _serverSocket, _clientSocket;
            List<Socket> listSockets= new List<Socket>();
            List<string> listNicks = new List<string>();
            private byte[] _buffer;
            string path= @"C:\Users\haker_000\Documents\visual studio 2012\Projects\Chat\Client\bin\Debug\Client.exe";
            private byte[] _buffernick;
            bool enable = false;
            int users = 0;
            Thread _th;
    
            public Form1()
            {
                InitializeComponent();
                Process.Start(path);
            }
    
            
    
            private void StartServer()
            {
                try
                {
                    _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 3333));
                    _serverSocket.Listen(0);
                    _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
                    enable = true;
                    button3.Enabled = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK);
                }
            }
    
            private void AcceptCallback(IAsyncResult ar)
            {
                try
                {
                    _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    _clientSocket = _serverSocket.EndAccept(ar);
                    users++;
                    label2.Text = users.ToString();
                    listSockets.Add(_clientSocket);
                    
                    _buffer = new byte[_clientSocket.ReceiveBufferSize];
                    _buffernick = new byte[_clientSocket.ReceiveBufferSize];
                    _clientSocket.BeginReceive(_buffernick, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveNickCallback), null);
                    _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
                    
                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK);
                }
            }
    
            private void ReceiveNickCallback(IAsyncResult ar)
            {
    
                try
                {
                    _clientSocket.EndReceive(ar);
    
                    string nick = Encoding.Unicode.GetString(_buffernick);
                    listNicks.Add(nick);
                    textBox3.AppendText("\r\n" + nick);
                    AppendNickToTextBox(nick);
                    SentToAllClients("Welcome "+nick+ "!");
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK);
                }
            }
        
    
            private void AppendNickToTextBox(string text)
            {
                MethodInvoker invoker = new MethodInvoker(delegate
                {
                    textBox2.Text += "\r\n"+ "Welcome " + text;
                });
                this.Invoke(invoker);
            }
    
            private void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    string text = null;
                    
                    int received = _clientSocket.EndReceive(ar);
                    Array.Resize(ref _buffer, received);
                    text = Encoding.Unicode.GetString(_buffer);
                    AppendToTextBox(text);
                    Array.Resize(ref _buffer, _clientSocket.ReceiveBufferSize);
                    
                    _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
                    SentToAllClients(text);
                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK);
                }
            }
    
            private void SentToAllClients(string text)
            {
                byte[] _sendText = Encoding.Unicode.GetBytes(text);
                
                    try
                    {
                        _clientSocket.BeginSend(_sendText, 0, _sendText.Length, SocketFlags.None, new AsyncCallback(SendnickCallback), null);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK);
                    }
                
    
            }
    
            private void SendnickCallback(IAsyncResult ar)
            {
                
                    try
                    {
                        if (_clientSocket.ReceiveBufferSize > 0)
                        {
                            _clientSocket.EndSend(ar);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                
            }
    
            private void AppendToTextBox(string text)
            {
                MethodInvoker invoker = new MethodInvoker(delegate
                    {
                        textBox2.Text += "\r\n" + text;
                    });
                this.Invoke(invoker);
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                StartServer();
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (enable == true)
                {
                    _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
                }
            }
    
            
        }
    }
    
    в общем как сделать мультиклиентским?