Aplikacja typu Czat , polaczenie 2 klientów nie dziala

0

Witam, wykonałem projekt czatu zgodnie z książką http://pdf.helion.pl/cshta2/cshta2.pdf . Jest to moja pierwsza aplikacja sieciowa i mam pewien problem, mianowicie komunikacja miedzy 1 klientem a serwerem działa ale miedze 2 klientami a serwerem nie . Nie wiem czy jest to problem z portami czy z IP wiec proszę o pomoc. Projekt pod linkiem http://www.speedyshare.com/QqkHp/Projects.rar

0

Kod Serwera ( zgory przepraszam jesli zbyt chaotycznie napisane)

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;
using System.Net.Sockets;
using System.Collections;
using System.IO;


namespace CzatSerwer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            clientsList = new ArrayList();
            namesClients = new ArrayList();
            isServerActive = false;
            webBrowserChat.Document.Write("<html><head><style>body,table{ font-size: 10pt; font-family: Verdana; margin: 3px 3px 3px 3px;font-color: black;}</style></head><body width=\""+ 
            (webBrowserChat.ClientSize.Width - 20).ToString() + "\">");
        }

        private void AddText(string who, string message)
        {
            SetTextHTML("<table><tr><td width=\"10%\"><b>[" + who + "]: </b></td>");
            SetTextHTML("<td colspan=2>" + message + "</td></tr></table>"); SetScroll();
        }

        private void SendUdpMessage(string message)
        {
            foreach (string user in listBoxUsers.Items) using (UdpClient klientUDP = new UdpClient(user, 2500))
                { byte[] bufor = Encoding.UTF8.GetBytes(message);
                    klientUDP.Send(bufor, bufor.Length);
                }
        }

    
        void clientThread_DoWork(object sender, DoWorkEventArgs e)
        {
            IPEndPoint IP = (IPEndPoint)client.Client.RemoteEndPoint;
            SetText(listBoxUsers, IP.Address.ToString());
            SetText(listBoxServer, "Klient [" + IP.Address.ToString() + "] uwieżytelniony");
            NetworkStream ns = client.GetStream();
            BinaryReader read = new BinaryReader(ns);
            string[] cmd = null; BackgroundWorker bw = (BackgroundWorker)sender;
            try
            {
                while ((cmd = read.ReadString().Split(new char[] { ':' }))[1] !="BYE" && bw.CancellationPending == false)
                {
                    string message = null; if (cmd.Length > 2) { message = cmd[2]; for (int i = 3; i < cmd.Length; i++) message += ":" + cmd[i];
                    }
                    switch (cmd[1])
                    {
                        case "SAY": AddText(cmd[0], message);
                            SendUdpMessage(cmd[0] + ":" + cmd[1] + ":" + message);
                            break;
                    }
                }
                SetText(listBoxServer, "Użytkownik [" + cmd[0] + "] opuścił serwer");
                for (int i = 0; i < listBoxUsers.Items.Count; i++)
                    if (IP.Address.ToString() == listBoxUsers.Items[i].ToString()) { RemoveText(i);
                        namesClients.RemoveAt(i);
                        clientsList.RemoveAt(i);
                    }
                SendUdpMessage("administrator:SAY:Użytkownik " + cmd[0] + " opuścił rozmowę");
                read.Close();
                ns.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    

        private TcpListener server;
        private TcpClient client;
        private ArrayList clientsList;
        private ArrayList namesClients;
        private bool isServerActive;



        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                server.Start(); SetText(listBoxServer, "Serwer oczekuje na połączenia ...");
                while (true)
                {
                    client = server.AcceptTcpClient();
                    SetText(listBoxServer, "Klient podłączony");
                    NetworkStream ns = client.GetStream();
                    BinaryReader read = new BinaryReader(ns);
                    string data = read.ReadString();
                    string[] cmd = data.Split(new char[] { ':' }); if (cmd[1] == "HI")
                    {
                        BinaryWriter write = new BinaryWriter(ns);
                        if (namesClients.BinarySearch(cmd[0]) > -1)
                        {
                            write.Write("ERROR:Użytkownik o podanej nazwie już istnieje");
                        }
                        else
                        {
                            write.Write("HI"); BackgroundWorker clientThread = new BackgroundWorker();
                            clientThread.WorkerSupportsCancellation = true;
                            clientThread.DoWork += new DoWorkEventHandler(clientThread_DoWork);
                            namesClients.Add(cmd[0]);
                            clientsList.Add(clientThread);
                            clientThread.RunWorkerAsync();
                            SendUdpMessage("administrator:SAY:Użytkownik " + cmd[0] + " dołączył do rozmowy");
                        }
                    }
                    else
                    {
                        MessageBox.Show("Klient nie dokonał autoryzacji");
                        isServerActive = false; client.Close();
                    }
                }
            }
            catch
            {
                isServerActive = false; server.Stop(); SetText(listBoxServer, "Połączenie przerwane");
            }
        }

        delegate void SetTextCallBack(ListBox lista, string tekst);
        private void SetText(ListBox lista, string tekst)
        {
            if (lista.InvokeRequired)
                {
                SetTextCallBack f = new SetTextCallBack(SetText);
                this.Invoke(f, new object[] { lista, tekst });
                    }
                     else { lista.Items.Add(tekst);
                     }
                }
        delegate void SetTextHTMLCallBack(string tekst);
        private void SetTextHTML(string tekst)
        {
            if (webBrowserChat.InvokeRequired)
            {
                SetTextHTMLCallBack f = new SetTextHTMLCallBack(SetTextHTML);
                this.Invoke(f, new object[] { tekst });
            }
            else
            {
                this.webBrowserChat.Document.Write(tekst);
            }
        }
        delegate void SetScrollCallBack(); private void SetScroll()
        {
            if (webBrowserChat.InvokeRequired)
            {
                SetScrollCallBack f = new SetScrollCallBack(SetScroll);
                this.Invoke(f);
            }
            else
            {
                this.webBrowserChat.Document.Window.ScrollTo(1, int.MaxValue);
            }
        }
        delegate void RemoveTextCallBack(int i);
        private void RemoveText(int i)
        {
            if (listBoxUsers.InvokeRequired)
            {
                RemoveTextCallBack f = new RemoveTextCallBack(RemoveText);
                this.Invoke(f, new object[] { i });
            }
            else
            {
                listBoxUsers.Items.RemoveAt(i);
            }
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (!isServerActive)
                try
                {
                    server = new TcpListener(IPAddress.Parse(comboBoxIpAddress.Text),(int)numericUpDownPort.Value);
                    backgroundWorkerMainLoop.RunWorkerAsync();
                    isServerActive = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Błąd inicjacji serwera (" + ex.Message + ")");
                }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (isServerActive)
            {
                SendUdpMessage("administrator:SAY:Serwer zostanie wyłączony");
                if (client != null) client.Close();
                server.Stop();
                listBoxServer.Items.Add("Serwer wyłączony");
                listBoxUsers.Items.Clear();
                namesClients.Clear();
                clientsList.Clear();
            }
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            if (textBoxMessage.Text != String.Empty && textBoxMessage.Text.Trim()!= String.Empty)
            {
                AddText("administrator", textBoxMessage.Text);
                if (isServerActive) SendUdpMessage("administrator:SAY:" + textBoxMessage.Text);
            }
        }
        private void textBoxMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) buttonStop_Click(this, null);
        }

        private void buttonRemove_Click_1(object sender, EventArgs e)
        {
            int index = listBoxUsers.SelectedIndex;
            using (UdpClient clientUdp = new UdpClient(listBoxUsers.Items[index].ToString(), 2500))
            {
                byte[] buff = Encoding.UTF8.GetBytes("administrator:SAY:Zostałeś odłączony");
                clientUdp.Send(buff, buff.Length);
                byte[] bufor2 = Encoding.UTF8.GetBytes("administrator:BYE:pusty");
                clientUdp.Send(bufor2, bufor2.Length);
            }
            listBoxServer.Items.Add("Klient [" + listBoxUsers.Items[index].ToString() + "] rozłączony");
            ((BackgroundWorker)clientsList[index]).CancelAsync();
            SendUdpMessage("administrator:SAY:Użytkownik " + listBoxUsers.Items[index].ToString() + " został odłączony");
            listBoxUsers.Items.RemoveAt(index);
            clientsList.RemoveAt(index); namesClients.RemoveAt(index);
        }

        private void numericUpDownPort_ValueChanged(object sender, EventArgs e)
        {

        }
    }
}
 
0

kod klienta

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;
using System.Net.Sockets;
using System.IO;

namespace CzatKlient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            webBrowserChat.Document.Write("<html><head><style>body,table { font-size:10pt; font-family: Verdana; margin: 3px 3px 3px 3px; font-color:black;}</style></head><body width=\"" +
            (webBrowserChat.ClientSize.Width-20).ToString() + "\">");
        }
        private TcpClient client;
        private string addressIPServer = "127.0.0.1";
        private BinaryWriter write;
        private bool isActive = false;

        private void AddText(string who, string message)
        {
            SetTextHTML("<table><tr><td width=\"10%\"><b>[" + who + "]: </b></td>");
            SetTextHTML("<td colspan=2>" + message + "</td></tr></table>");
            SetScroll();
        }
  
      

       
        private void textBoxMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.buttonSend_Click_1(sender, null);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (write != null)
            {
                try
                {
                    write.Write(textBoxNick.Text + ":BYE:" + "pusty");
                    write.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Błąd");
                }
            }
            if (backgroundWorkerMainThread.IsBusy)
                backgroundWorkerMainThread.CancelAsync();
            if (client != null)
                client.Close();
        }
       



        delegate void SetTextHTMLCallBack(string tekst);
        private void SetTextHTML(string tekst)
        {
            if (webBrowserChat.InvokeRequired)
            {
                SetTextHTMLCallBack f = new SetTextHTMLCallBack(SetTextHTML);
                this.Invoke(f, new object[] { tekst });
            }
            else
            {
                this.webBrowserChat.Document.Write(tekst);
            }
        }
        delegate void SetScrollCallBack(); private void SetScroll()
        {
            if (webBrowserChat.InvokeRequired)
            {
                SetScrollCallBack f = new SetScrollCallBack(SetScroll);
                this.Invoke(f);
            }
            else
            {
                this.webBrowserChat.Document.Window.ScrollTo(1, int.MaxValue);
            }
        }
        delegate void RemoveTextCallBack(int i);
        private void RemoveText(int i)
        {
            if (listBoxUsers.InvokeRequired)
            {
                RemoveTextCallBack f = new RemoveTextCallBack(RemoveText);
                this.Invoke(f, new object[] { i });
            }
            else
            {
                listBoxUsers.Items.RemoveAt(i);
            }
        }

     

        private void buttonConnect_Click_1(object sender, EventArgs e)
        {
            try
            {
                if (textBoxNick.Text != String.Empty)
                {
                    client = new TcpClient(addressIPServer, 2501); //6969
                    textBoxNick.ReadOnly = true;
                    NetworkStream ns = client.GetStream();
                    write = new BinaryWriter(ns);
                    write.Write(textBoxNick.Text + ":HI:" + "pusty");
                    BinaryReader read = new BinaryReader(ns);
                    string answer = read.ReadString();
                    if (answer == "HI")
                    {
                        backgroundWorkerMainThread.RunWorkerAsync();
                        isActive = true; buttonConnect.Enabled = false;
                    }
                    else
                    {
                        MessageBox.Show("Serwer odmawia nawiązania połączenia");
                        buttonConnect.Enabled = true;
                        client.Close();
                    }
                }
                else MessageBox.Show("Wpisz swój nick");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Nie można nawiązać połączenia " + ex.Message);
            }
        }

        private void buttonSend_Click_1(object sender, EventArgs e)
        {
            if (isActive && textBoxMessage.Text != String.Empty)
                write.Write(textBoxNick.Text + ":SAY:" + textBoxMessage.Text);
            textBoxMessage.Text = String.Empty;
        }

        private void buttonDisconnect_Click_1(object sender, EventArgs e)
        {
            Close();
        }

        private void backgroundWorkerMainThread_DoWork_1(object sender, DoWorkEventArgs e)
        {
            UdpClient client = new UdpClient(2500);
            IPEndPoint addressIP = new IPEndPoint(IPAddress.Parse(addressIPServer), 0);
            string message = "";
            while (!backgroundWorkerMainThread.CancellationPending)
            {
                Byte[] bufor = client.Receive(ref addressIP);
                string data = Encoding.UTF8.GetString(bufor);
                string[] cmd = data.Split(new char[] { ':' });
                if (cmd[1] == "BYE")
                {
                    AddText("system", "klient odłączony");
                    client.Close(); return;
                }
                if (cmd.Length > 2)
                {
                    message = cmd[2];
                    for (int i = 3; i < cmd.Length; i++) message += ":" + cmd[i];
                }
                AddText(cmd[0], message);
            }
        }
    }
} 
0

Kod aż pali w oczy, aż boje się go odpalić :)

Używałeś debuggera?
Jakiś wyjątek jest rzucany, jeżeli tak w której linii.
Co znaczy że nie działa ?

0

Jeśli chodzi o kod, żadnych błędów nie ma, działa w ten sposób : odpalam serwer ustawiam port klienta (w tym przepadku 2501) , włączam klienta łącze się i przesyłanie wiadomości działa, ale nie działa przysłanie , a nawet połączenie się 2 klienta ponieważ jest na tym samym porcie ( tak mi się wydaje) i nie wiem jak to zmienić.
Co do debuggowania to standardowo w Visual Studio, chyba że służy do tego inny program o którym nie mam pojęcia.
Tak jak już dodałem kod może być chaotyczny przez mój brak wiedzy na temat kolejności danych funkcji, metod w kodzie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1