Risultati da 1 a 2 di 2
  1. #1

    Registrato da
    Dec 2010
    Messaggi
    2,283
    Reputazione (?)
    55
    Piaciuto (?)
    463
    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:
    1. Se ci sono nuove connessioni
    2. Se ci sono pacchetti in arrivo
    3. 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<
    TcpClientclients = new List<TcpClient>();
            static List<
    NetworkStreamstream = 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<= clients.Count -1i++)
                    {
                        try
                        {
                           
                            if (
    clients[i].Available 0)
                            {
                                
    byte[] buffer = new byte[clients[i].Available];
                                
    stream[i].Read(buffer0buffer.Length);
                                
    Console.WriteLine("[{0}]: Received packet from {1}:\n\t{2}"DateTime.Now,((IPEndPoint)clients[i].Client.RemoteEndPoint).AddressSystem.Text.UTF8Encoding.UTF8.GetString(buffer));
                            }
                        }
                        catch (
    Exception ex) {  }
                    }

                    
    Thread.Sleep(1);
                }
            }

            
            static 
    void CatchDrops()
            {
                while (
    true)
                {
                    for (
    int i clients.Count 1>= 0i--)
                    {
                        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.Nowtmpip);
                            }
                        }
                        catch (
    Exception ex) { }
                    }
                    
    Thread.Sleep(1);
                }

            }

            static 
    bool SocketConnected(TcpClient tcp)
            {
                if (
    tcp.Client.Poll(0SelectMode.SelectRead))
                {
                    
    byte[] buff = new byte[1];
                    if (
    tcp.Client.Receive(buffSocketFlags.Peek) == 0) return false;
                }
                return 
    true;
            }

        }

    Non riesco a capire come mai Available rimane uno

    Grazie per l'aiuto
    Firma di Errør218
    #In girum imus nocte et consumimur igni.
    #Hardcore Dyrus Fan.


    And then it happened, a door opened to a world...
    Rushing through the phone line like heroin through an addict's veins,
    An electronic pulse is sent out, a refuge from the day-to-day incompetencies is sought...
    A board is found.
    "This is it... this is where I belong..."
    I know everyone here...


  2.  

  3. #2

    Registrato da
    Jul 2012
    Messaggi
    169
    Reputazione (?)
    1
    Piaciuto (?)
    27
    ho notato che quando un utente si disconnette e il suo client viene rimosso da "clients", non viene rimosso il suo NetworkStream
    Ti consiglio di creare una struttura dove hai Client e stream, cosi potrai gestirli più facilmente...

    p.s: Anche se la lista degli stream è inutili in quanto dal Client puoi ottenere il networkstream con la funzione: "GetStream()"
    Ultima modifica di WareX; 15/09/12 alle 15:58

  4.  

Ti consigliamo di leggere anche...

  1. threading waitone?
    Di toothless nel forum VB / VB.NET
    Risposte: 9
    Ultimo Messaggio: 22/07/12, 11:28

Pubblicità
StratoKyke Youtube GameFanShop

I visitatori sono atterrati su questa pagina cercando:

Nessuno è atterrato su questa pagina da un motore di ricerca. Almeno, non per ora...
SEO Blog

Segnalibri

Permessi di Scrittura

  • Tu non puoi inviare nuove discussioni
  • Tu non puoi inviare risposte
  • Tu non puoi inviare allegati
  • Tu non puoi modificare i tuoi messaggi
  •