2010-09-27 91 views
5

Estoy empezando a meterme en el mundo de la programación de redes y recientemente me encontré con una muestra bastante antigua de un tutorial de conferenciantes (o lo que soy dicho)."No se pueden leer los datos de la conexión de transporte" - C#

Lo intentamos en las computadoras de la universidad, pero no funcionó, por lo que el conferenciante asumió que se trataba de una configuración de seguridad ya sea por Windows 7 o por los sistemas informáticos de la universidad.

Ansioso por encontrar la causa, decidí ejecutar el mismo código en mi propia computadora en casa y no fue una sorpresa que no funcionara.

Hay dos proyectos en una solución, uno actúa como el cliente y otro como el servidor. Una vez que el servidor y el cliente están conectados entre sí, el cliente envía una cadena simple al servidor que se imprime en la consola. Después de esto, las conexiones apropiadas se cierran y la aplicación sale con gracia.

Las aplicaciones funcionan por lo que el servidor confirma que se ha conectado con el cliente, sin embargo, se produce una excepción (que se detecta y gestiona) con el texto:

No se puede leer los datos de la conexión de transporte : Una conexión existente fue cerrada a la fuerza por el host remoto. - (System.IO.IOException)

Ahora que estoy empezando con la programación de la red con C# No estoy muy seguro de dónde buscar, mi profesor dijo que iba a descubrir por la conferencia de la próxima semana con la causa y la solución del problema, pero quería tomar una iniciativa y descubrirme a mí mismo.

He agregado las clases Client.cs y Server.cs en caso de que sean útiles, el depurador sugiere que la causa se encuentra en la línea 27 en Server.cs, la llamada a streamReader.Readline();

Nota: Esto no es de ninguna manera la tarea, simplemente tengo curiosidad de por qué no funciona. Diga que es una experiencia de aprendizaje =]

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

Me sorprendería que esto haya funcionado alguna vez. El NetworkStream creado cada iteración será eliminado de forma no determinista por el GC, lo que causará que la conexión subyacente se cierre.Voy a componer un ejemplo que debería funcionar. – dtb

+0

¿Cuidar para elaborar? –

Respuesta

1

probar este código de servidor:

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(); 

Esta escucha en el puerto 1234 , acepta un cliente, crea un StreamReader y emite todas las líneas enviadas por e cliente hasta que el cliente cierre la conexión. Luego deja de escuchar y sale.

Como puede ver, solo se crea un StreamReader (no repetidamente para cada línea), y tanto el TcpClient como el StreamReader se eliminan mediante la declaración using cuando termina.


Su código de cliente debería funcionar. También es una buena idea deshacerse de los objetos aquí:

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

Esto puede parecer una pregunta un poco novedosa, pero ¿cómo es que AcceptTcpCLient se está utilizando no no con AcceptSocket? ¿Hay algún beneficio en usar uno sobre el otro? –

+1

.NET Framework proporciona dos formas de programación de red: TcpClient/TcpListener y Sockets. TcpClient/TcpListener ofrecen una interfaz de alto nivel y son mucho más simples y fáciles de usar que los Sockets de bajo nivel. Por lo tanto, es una buena idea que un principiante use TcpClient/TcpListener y evite Sockets. – dtb

+0

Ezxcellent, gracias por el consejo. Después de cambiar el Server.cs a su solución, el mensaje se envía a través pero luego arroja una IOException en la línea donde intenta leer el mensaje del cliente. –

Cuestiones relacionadas