2010-09-27 25 views
5

Sto iniziando a immergere le dita dei piedi nel mondo della programmazione di rete e recentemente ho trovato un campione abbastanza vecchio da un tutorial di docenti (O almeno così sono detto)."Impossibile leggere i dati dalla connessione di trasporto" - C#

L'abbiamo provato sui computer universitari ma non funzionava, quindi il docente ha assunto che fosse impostato su un ambiente di sicurezza tramite Windows 7 o i sistemi informatici dell'università.

Desideroso di trovare la causa, ho deciso di eseguire lo stesso codice sul mio computer a casa e nessuna sorpresa non ha funzionato.

Esistono due progetti in una soluzione, uno funge da client e da un altro server. Una volta che il server e il client sono entrambi collegati tra loro, il client invia una semplice stringa al server che viene stampata sulla console. Dopodiché vengono chiuse le connessioni appropriate e l'applicazione esce con grazia.

Le applicazioni funzionano per quanto riguarda il server conferma che esso è connesso al cliente ma viene generata un'eccezione (che viene catturato e manipolati) con il testo:

Impossibile leggere i dati dal collegamento : Una connessione esistente è stata forzatamente chiusa dall'host remoto. - (System.IO.IOException)

Ora, mentre io sono solo agli inizi con la programmazione di rete con C# Io non sono esattamente sicuro dove guardare, il mio professore ha detto che avrebbe trovato fuori per conferenza della prossima settimana con la causa e la soluzione al problema, ma ho voluto prendere qualche iniziativa e scoprire me stesso.

Ho aggiunto le classi Client.cs e Server.cs nel caso in cui siano utili, il debugger suggerisce che la causa si trova alla riga 27 in Server.cs, la chiamata a streamReader.Readline();

Nota: Questo non è in alcun modo compito a casa, sono semplicemente curioso di sapere perché non funziona. Chiamatela un'esperienza di apprendimento =]

Client.cs

using System; 
using System.Net.Sockets; 
using System.IO; 

namespace NetworkProgrammingTutorial1Client 
{ 
    class Client 
    { 
     static void Main(string[] args) 
     { 
      TcpClient myclient; 

      try 
      { 
       // Create a TcpClient to talk to the local host. 
       myclient = new TcpClient("localhost", 1234); 
      } 
      catch 
      { 
       Console.WriteLine("Failed to connect to the server."); 
       return; 
      } 

      // get a Network stream from the server 
      NetworkStream networkStream = myclient.GetStream(); 
      StreamWriter streamWriter = new StreamWriter(networkStream); 

      streamWriter.WriteLine("Have a message."); 
      streamWriter.Flush(); 
     } 
    } 
} 

Server.cs

using System; 
using System.Net.Sockets; 
using System.Net; 
using System.IO; 

namespace NetworkProgrammingTutorial1Server 
{ 
    class Server 
    { 
     static void Main(string[] args) 
     { 
      // TcpListener is listening on the given port...             { 
      TcpListener tcpListener = new TcpListener(1234); 
      tcpListener.Start();  
      Console.WriteLine("Server Started") ;     
      // Accepts a new connection... 
      Socket socketForClient = tcpListener.AcceptSocket();     
      try 
      { 
       if (socketForClient.Connected) 
       { 
        while (true) 
        { 
         Console.WriteLine("Client connected"); 
         NetworkStream networkStream = new NetworkStream(socketForClient); 
         StreamReader streamReader = new StreamReader(networkStream); 
         string line = streamReader.ReadLine(); 
         if (line == null) 
          break; 
         Console.WriteLine(line); 
        } 
       } 

       socketForClient.Close();    
       Console.WriteLine("Exiting..."); 
      } 
      catch(Exception e) 
      { 
       Console.WriteLine(e.ToString()) ; 
      } 
     } 
    } 
} 
+0

Sarei sorpreso se questo ha funzionato. NetworkStream creato ogni iterazione verrà eliminato dal GC in modo non deterministico, causando la chiusura della connessione sottostante.Comporrò un esempio che dovrebbe funzionare. – dtb

+0

Cura da elaborare? –

risposta

1

provare questo codice server:

TcpListener listener = new TcpListener(IPAddress.Any, 1234); 
listener.Start();  

using (TcpClient client = listener.AcceptTcpClient()) 
using (StreamReader reader = new StreamReader(client.GetStream())) 
{ 
    string line; 
    while ((line = reader.ReadLine()) != null) 
    { 
     Console.WriteLine(line); 
    } 
} 

listener.Stop(); 

Questo ascolto sulla porta 1234 , accetta un client, crea uno StreamReader e genera tutte le righe inviate da th e client fino a quando il client non chiude la connessione. Quindi smette di ascoltare ed esce.

Come si può vedere, viene creato un solo StreamReader (non ripetutamente per ogni riga), e sia il TcpClient che lo StreamReader sono disposti dall'istruzione using al termine.


Il codice cliente dovrebbe funzionare. È comunque una buona idea disporre degli oggetti anche qui:

using (TcpClient client = new TcpClient("localhost", 1234)) 
using (StreamWriter writer = new StreamWriter(client.GetStream())) 
{ 
    writer.WriteLine("Have a message."); 
    writer.Flush(); 

    writer.WriteLine("Have another message."); 
    writer.Flush(); 
} 
+0

Questa domanda potrebbe sembrare un po 'approssimativa, ma come mai AcceptTcpCLient viene utilizzato non AcceptSocket? C'è un vantaggio nell'usare l'uno sull'altro? –

+1

.NET Framework offre due modalità di programmazione di rete: TcpClient/TcpListener e Sockets. TcpClient/TcpListener offre un'interfaccia di alto livello e sono molto più semplici e facili da usare rispetto ai socket di basso livello. Quindi è una buona idea per un principiante usare TcpClient/TcpListener ed evitare Sockets. – dtb

+0

Ezxcellent, grazie per il consiglio. Dopo aver modificato Server.cs nella soluzione, il messaggio viene inviato ma dopo viene generata una IOException sulla linea in cui tenta di leggere il messaggio dal client. –

Problemi correlati