Da ieri sera lavoro a un tcp receiver, per scopi di studio...
Sto studiando il protocollo TCP, e ho creato questo 'sample server' multi-client (mannaggia a me) utilizzando le liste e ovviamente multi-threading ...
Fatto sta che ho creato 3 thread per controllare:
- Se ci sono nuove connessioni
- Se ci sono pacchetti in arrivo
- Se qualcuno si è disconnesso
Il problema sorge quando un utente si disconnette...
Tutto è ok, solo che quando un utente si riconnette e invia un pacchetto il programma si impalla e continua a leggere lo stream e Available rimane sempre 1!
Eccovi il source:
Codice PHP:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
namespace TCP_Receiver
{
class Program
{
static TcpListener list;
static List<TcpClient> clients = new List<TcpClient>();
static List<NetworkStream> stream = new List<NetworkStream>();
static Thread connectionCatcher;
static Thread packetCatcher;
static Thread dropCatcher;
static void Main(string[] args)
{
Console.Write("\n" +
"\t\t ______ ___ __ ___ \n" +
"\t\t| ____| |__ \\/_ |/ _ \\ \n" +
"\t\t| |__ _ __ _ __ ___ _ __ ) || | (_) |\n" +
"\t\t| __| | '__| '__/ _ \\| '__/ / | |> _ < \n" +
"\t\t| |____| | | | | (_) | | / /_ | | (_) |\n" +
"\t\t|_______|_| |_| \\___/|_||____||_|\\___/ \n" +
"\n\n\tWelcome to the TCP Receiver, only for the purpose of study.\n\n\nPort to listen: ");
int Port;
Port = Convert.ToUInt16(Console.ReadLine());
list = new TcpListener(Port);
list.Start();
connectionCatcher = new Thread(CatchConnections);
connectionCatcher.IsBackground = true;
connectionCatcher.Start();
Console.WriteLine("Server started succeffully and it's listening at port {0}.", Port.ToString());
Thread.CurrentThread.Suspend();
}
static void CatchConnections()
{
TcpClient tmpclient;
while (true)
{
if (list.Pending())
{
if (clients.Count == 0)
{
packetCatcher = new Thread(CatchPackets);
packetCatcher.IsBackground = true;
packetCatcher.Start();
dropCatcher = new Thread(CatchDrops);
dropCatcher.IsBackground = true;
dropCatcher.Start();
}
clients.Add(list.AcceptTcpClient());
tmpclient = clients[clients.Count - 1];
stream.Add(tmpclient.GetStream());
Console.WriteLine("[{0}]: Connection received from {1}", DateTime.Now,((IPEndPoint)tmpclient.Client.RemoteEndPoint).Address);
}
Thread.Sleep(1);
}
}
static void CatchPackets()
{
while (true)
{
for (int i = 0; i <= clients.Count -1; i++)
{
try
{
if (clients[i].Available > 0)
{
byte[] buffer = new byte[clients[i].Available];
stream[i].Read(buffer, 0, buffer.Length);
Console.WriteLine("[{0}]: Received packet from {1}:\n\t{2}", DateTime.Now,((IPEndPoint)clients[i].Client.RemoteEndPoint).Address, System.Text.UTF8Encoding.UTF8.GetString(buffer));
}
}
catch (Exception ex) { }
}
Thread.Sleep(1);
}
}
static void CatchDrops()
{
while (true)
{
for (int i = clients.Count - 1; i >= 0; i--)
{
try
{
if (!SocketConnected(clients[i]))
{
string tmpip = ((IPEndPoint)clients[i].Client.RemoteEndPoint).Address.ToString();
clients.Remove(clients[i]);
Console.WriteLine("[{0}]: Connection lost from {1}", DateTime.Now, tmpip);
}
}
catch (Exception ex) { }
}
Thread.Sleep(1);
}
}
static bool SocketConnected(TcpClient tcp)
{
if (tcp.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (tcp.Client.Receive(buff, SocketFlags.Peek) == 0) return false;
}
return true;
}
}
}
Non riesco a capire come mai Available rimane uno 
Grazie per l'aiuto
Segnalibri