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
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)
{
}
}
}
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);
}
}
}
}
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 ?
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.