Witam, zacząłem bawić się w programowanie sieciowe w C#. Chciałem zrobić sobie prosty chat, na lokalnym połączeniu, ale jak uruchamiam serwer, klienta jednego odpale to wszystko ok działa fajnie tak jak powinien, problem wychodzi gdy drugi raz chce uruchomić program klienta. Łaczę się pod innym loginem, ale nic z tego. Bo takjakby powielało połączenie drugie. W Drugim oknie klienta nie wyświetla tego co pisze się na czacie a jeżeli się już wyśle to wysyła dwa razy. Mogłby ktoś przetestować i zobaczyć w kod i podpowiedzieć co robie źle. Kazda wskazówka się przyda :)
KLIENT
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Collections;
namespace CzatKlient
{
public partial class Form1 : Form
{
delegate void SetTextCallBack(ListBox lista, string tekst); //++
delegate void SetTextHTMLCallBack(string tekst); //+
delegate void SetScrollCallBack(); //+
private TcpClient client;
private string addressIPServer = "127.0.0.1";
private BinaryWriter write;
private bool isActive = false;
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 void SetTextHTML(string tekst)
{
if (webBrowserChat.InvokeRequired)
{
SetTextHTMLCallBack f = new SetTextHTMLCallBack(SetTextHTML);
this.Invoke(f, new object[] { tekst });
}
else
{
this.webBrowserChat.Document.Write(tekst);
}
} //+
private void AddText(string who, string message)
{
SetTextHTML("<table><tr><td width=\"10%\"><b>[" + who + "]:</b></td>");
SetTextHTML("<td colspan=2>" + message + "</td></td></table>");
SetScroll();
}//+
private void SetScroll()
{
if (webBrowserChat.InvokeRequired)
{
SetScrollCallBack f = new SetScrollCallBack(SetScroll);
this.Invoke(f);
}
else
{
this.webBrowserChat.Document.Window.ScrollTo(1, int.MaxValue);
}
}//+
private void backgroundWorkerMainThread_DoWork(object sender, DoWorkEventArgs e)
{
UdpClient client = new UdpClient(2500);
IPEndPoint addresIP = new IPEndPoint(IPAddress.Parse(addressIPServer), 0);
string message = "";
while(!backgroundWorkerMainThread.CancellationPending)
{
Byte[] bufor = client.Receive(ref addresIP);
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);
}
} //+
private void buttonConnect_Click(object sender, EventArgs e)
{
try
{
if (textBoxNick.Text != String.Empty)
{
client = new TcpClient(addressIPServer, 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łaczenia");
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(object sender, EventArgs e)
{
if (isActive && textBoxMessage.Text != String.Empty)
write.Write(textBoxNick.Text + ":SAY:" + textBoxMessage.Text);
textBoxMessage.Text = String.Empty;
}
private void textBoxMessage_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
this.buttonSend_Click(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();
}
private void buttonDisconnect_Click(object sender, EventArgs e)
{
Close();
}
}
}
SERWER:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Collections;
namespace CzatSerwer
{
public partial class Form1 : Form
{
#region delgacje
delegate void SetTextCallBack(ListBox lista, string tekst);//+
delegate void SetTextHTMLCallBack(string tekst); //+
delegate void SetScrollCallBack();//+
delegate void RemoveTextCallBack(int i);//+
#endregion
#region pola
private TcpListener server;
private TcpClient client;
private ArrayList clientsList;
private ArrayList namesClients;
private bool isServerActive;
#endregion //+
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 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);
}
} // +
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);
}
} // +
private void SetScroll()
{
if (webBrowserChat.InvokeRequired)
{
SetScrollCallBack f = new SetScrollCallBack(SetScroll);
this.Invoke(f);
}
else
{
this.webBrowserChat.Document.Window.ScrollTo(1, int.MaxValue);
}
} // +
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 AddText(string who, string message)
{
SetTextHTML("<table><tr><td width=\"10%\"><b>[" + who + "]:</b></td>");
SetTextHTML("<td colspan=2>" + message + "</td></td></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);
}
} //=
private void backgroundWorkerMainLoop_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:Uzytkownik " + 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");
}
} //+
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(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:SAY:pusty");
clientUdp.Send(bufor2, bufor2.Length);
}
listBoxServer.Items.Add("Klient [" + listBoxUsers.Items[index].ToString() + "] rozłączony");
((BackgroundWorker)clientsList[index]).CancelAsync();
SendUdpMessage("administrator:SAY:Uzytkownik " + listBoxUsers.Items[index].ToString() + " Został odłączony");
listBoxUsers.Items.RemoveAt(index);
clientsList.RemoveAt(index);
namesClients.RemoveAt(index);
} //+
private void backgroundWorkerClientThread_DoWork(object sender, DoWorkEventArgs e)
{
IPEndPoint IP = (IPEndPoint)client.Client.RemoteEndPoint;
SetText(listBoxUsers, IP.Address.ToString());
SetText(listBoxServer, "Klient [" + IP.Address.ToString() + "uwiezytelniony");
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:Uzytkownik " + cmd[0] + "opuscil rozmowe");
read.Close();
ns.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}//+
}
}