1
I have this online chat code using socket
and TCPListener
, but when the client simply disconnects abruptly or loses connection, it is not removed from the ArrayList
so-called clients.
public void ServiceClient()
{
Socket client = clientsocket;
bool keepalive = true;
while (keepalive)
{
Byte[] buffer = new Byte[1024];
client.Receive(buffer);
string clientcommand = System.Text.Encoding.UTF8.GetString(buffer);
string[] tokens = clientcommand.Split(new Char[] { '|' });
Console.WriteLine(clientcommand);
if (tokens[0] == "CONN")
{
for (int n = 0; n < clients.Count; n++)
{
Client cl = (Client)clients[n];
SendToClient(cl, "JOIN|" + tokens[1]);
}
EndPoint ep = client.RemoteEndPoint;
//string add = ep.ToString();
Client c = new Client(tokens[1], ep, clientservice, client);
clients.Add(c);
string message = "LIST|" + GetChatterList() + "\r\n";
SendToClient(c, message);
this.Invoke(new Action(() => lbClients.Items.Add(c.Name)));
//txtLogs.AppendText("-> SISTEMA: ", Color.Red);
//txtLogs.AppendText(DateTime.Now.ToString("HH:mm:ss") + "h - " + "Entrou no chat: " + c.Name, Color.White);
//txtLogs.AppendText("\r\n");
}
else if (tokens[0] == "CHAT")
{
for (int n = 0; n < clients.Count; n++)
{
Client cl = (Client)clients[n];
this.Invoke(new Action(() => SendToClient(cl, clientcommand)));
str = clientcommand;
var charsToRemove = new string[] { "CHAT|" };
foreach (var c in charsToRemove)
{
str = str.Replace(c, string.Empty);
}
}
//txtLogs.AppendText("-> CHAT: ", Color.DodgerBlue);
//txtLogs.AppendText(str, Color.White);
}
if (tokens[0] == "PRIV")
{
string destclient = tokens[3];
for (int n = 0; n < clients.Count; n++)
{
Client cl = (Client)clients[n];
if (cl.Name.CompareTo(tokens[3]) == 0)
{
SendToClient(cl, clientcommand);
var str = clientcommand;
var charsToRemove = new string[] { "PRIV|", "|", tokens[3] };
foreach (var c in charsToRemove)
{
str = str.Replace(c, string.Empty);
}
txtLogs.AppendText("-> PRIVADO: ", Color.Gold);
txtLogs.AppendText("Para: ", Color.LimeGreen);
txtLogs.AppendText(tokens[3], Color.White);
txtLogs.AppendText(" De: ", Color.LimeGreen);
txtLogs.AppendText(str, Color.White);
txtLogs.AppendText("\r\n");
}
if (cl.Name.CompareTo(tokens[1]) == 0)
{
SendToClient(cl, clientcommand);
var str = clientcommand;
var charsToRemove = new string[] { "PRIV|", "|", tokens[1] };
foreach (var c in charsToRemove)
{
str = str.Replace(c, string.Empty);
}
txtLogs.AppendText("-> PRIVADO: ", Color.Gold);
txtLogs.AppendText("Para: ", Color.LimeGreen);
txtLogs.AppendText(tokens[1], Color.White);
txtLogs.AppendText(" De: ", Color.LimeGreen);
txtLogs.AppendText(str, Color.White);
txtLogs.AppendText("\r\n");
}
}
}
else if (tokens[0] == "GONE")
{
int remove = 0;
bool found = false;
int c = clients.Count;
for (int n = 0; n < c; n++)
{
Client cl = (Client)clients[n];
SendToClient(cl, clientcommand);
if (cl.Name.CompareTo(tokens[1]) == 0)
{
remove = n;
found = true;
this.Invoke(new Action(() => lbClients.Items.Remove(cl.Name)));
txtLogs.AppendText("-> SISTEMA: ", Color.Red);
txtLogs.AppendText(DateTime.Now.ToString("HH:mm:ss") + "h - " + "Saiu no chat: " + cl.Name, Color.White);
txtLogs.AppendText("\r\n");
}
}
if (found)
clients.RemoveAt(remove);
client.Close();
keepalive = false;
}
/*else
{
int remove = 0;
bool found = false;
int c = clients.Count;
for (int n = 0; n < c; n++)
{
Client cl = (Client)clients[n];
SendToClient(cl, clientcommand);
if (cl.Name.CompareTo(tokens[1]) == 0)
{
remove = n;
found = true;
lbClients.Items.Remove(cl);
//lbClients.Items.Remove(cl.Name + " : " + cl.Host.ToString());
}
}
if (found)
this.Invoke(new Action(() => clients.RemoveAt(remove)));
client.Close();
keepalive = false;
}*/
}
}
With this, how to know if the customer is no longer operating and how to remove it from the ArrayList
and of ListBox
?
I do it with a
ReceiveTimeout
in theSocket
?– Marlon Pereira
At the moment, adding the
ReceiveTimeout
when there is abrupt disconnection, the server returns this: "It has been forced to cancel an existing connection by the remote host"– Marlon Pereira
think that this message you showed does not refer to the expired timeout, but rather to the socket closure by the client...to test the timeout control on the server you should leave the client running, but not sending anything to the server
– zentrunix