2010-10-22 6 views
2

Voici un problème vraiment étrange: Apparemment, la séquence spécifique d'octets qui se traduit par ASCII "PUttttt", si elle est envoyée via un socket TCP ne le rend pas du tout au client.Sockets cassés dans .NET?

J'ai inclus l'exemple de code utilisé pour illustrer le problème ci-dessous dans l'espoir que quelqu'un puisse avoir une idée de la raison pour laquelle cela se produit. Les applications serveur et client ont été intentionnellement réduites à de simples versions synchrones de console pour faciliter le dépannage.

L'aspect clé du problème est la donnée qui va dans le tampon d'envoi (la chaîne "PUttttt").

Le serveur:

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

namespace ConsoleServer 
{ 
    private static Socket mServer; 
    private static byte[] fileBytes; 
    private static int sent_total; 

    static void Main(string[] args) 
    { 
     string hostName = "localhost"; //Dns.GetHostName(); 
     IPHostEntry ipHostInfo = Dns.GetHostEntry(hostName); 
     IPAddress iaddr = null; 
     for(int k = 0; k < ipHostInfo.AddressList.Length; k++) 
      if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork) 
      { 
       iaddr = ipHostInfo.AddressList[k]; 
       break; 
      } 

     if (iaddr == null) 
     { 
      Console.WriteLine("Can not bind to any interface.. Server can not start"); 
      Console.ReadKey(); 
      return; 
     } 

     mServer = new Socket(iaddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 
     mServer.Bind(new IPEndPoint(iaddr, 8000)); 

     Console.WriteLine("Server: Bound to " + hostName + " (" + iaddr.ToString() + "):8000"); 
     mServer.Listen(1); 

     Console.WriteLine("Server: Started. Awaiting connection."); 

     Socket handler = mServer.Accept(); 
     handler.LingerState = new LingerOption(true, 5); 

     Console.WriteLine("Server: A Client connected\r\nServer: sending data"); 

     string str = @"PUttttt"; 
     fileBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(str); 

     SocketError errCode = SocketError.Success; 
     int sent = handler.Send(fileBytes, 0, fileBytes.Length, SocketFlags.None, out errCode); 
     sent_total += sent; 
     Console.WriteLine("Server: Done sending. " + sent_total + " bytes (" + errCode.ToString() + ")"); 

     handler.Close(); 

     Console.WriteLine("Server: CLient Disconnected"); 

     Console.ReadKey(); 
    } 
    } 
} 

Le client:

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

namespace ConsoleClient 
{ 
    class Program 
    { 
    private static int BUFFER_SIZE = 1024 * 1024; 
    private static string SERVER_ADDR = "localhost"; //Dns.GetHostName(); 
    private static int SERVER_PORT = 8000; 

    static void Main(string[] args) 
    { 
     Console.WriteLine("Client: connecting to " + SERVER_ADDR + " server"); 

     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     socket.ReceiveTimeout = 30000; 
     socket.ReceiveBufferSize = BUFFER_SIZE; 
     IPHostEntry ipHostInfo = Dns.GetHostEntry(SERVER_ADDR); 

     IPAddress ipAddress = null; 
     for (int k = 0; k < ipHostInfo.AddressList.Length; k++) 
      if (ipHostInfo.AddressList[k].AddressFamily == AddressFamily.InterNetwork) 
      { 
       ipAddress = ipHostInfo.AddressList[k]; 
       break; 
      } 

     socket.Connect(new IPEndPoint(ipAddress, SERVER_PORT)); 
     Console.WriteLine("Client: connected"); 

     byte[] buffer = new byte[BUFFER_SIZE]; 
     int total = 0; 
     int read = socket.Receive(buffer, buffer.Length, SocketFlags.None); 
     total += read; 

     Console.WriteLine("Client: read " + read + " bytes. " + total + " total"); 
     while (read > 0) 
     { 
      try 
      { 
       read = socket.Receive(buffer, buffer.Length, SocketFlags.None); 
       total += read; 

       Console.WriteLine("Client: read " + read + " bytes. " + total + " total: "); 
      } 
      catch (Exception se) 
      { 
       Console.WriteLine(se.ToString()); 
       break; 
      } 
     } 

     Console.WriteLine("Client: received " + total + " bytes"); 

     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 

     Console.WriteLine("Connection Closed."); 

     Console.ReadKey(); 
    } 
    } 
} 

J'ai compilé cette aide de Visual Studio 2010 et le .NET 4 Client Profile mais je pense qu'il est cassé dans d'autres versions de .NET.

est ici la sortie du serveur:

Server: Bound to localhost (127.0.0.1):8000 
Server: Started. Awaiting connection. 
Server: A Client connected 
Server: sending data 
Server: Done sending. 7 bytes (Success) 
Server: CLient Disconnected 

Et ceci est la sortie du client

Client: connecting to localhost server 
Client: connected 
Client: read 0 bytes. 0 total 
Client: received 0 bytes 
Connection Closed. 

Notez la différence entre ce qui est envoyé à partir du serveur et ce qui est reçu par le client . En outre, si la ligne qui ferme le socket sur le serveur est mise en commentaire, le client se bloque en attente de réception des données.

+1

Et ce code fonctionne pour tout sauf "PUttttt"? Cela semble être un bug vraiment improbable ... il doit y avoir quelque chose d'autre qui se passe –

+0

@Thomas, as-tu essayé de compiler et d'exécuter ce code? Ce qui est intéressant, c'est que le code fonctionne bien sur une machine mais j'en ai deux autres sur lesquels ça ne marche pas. Même les commentaires aussi simples que cela serait utile –

+0

Votre code fonctionne très bien sur ma machine (Vista, VS2008, .NET 3.5) –

Répondre

2

Cela semble peu probable, mais je peux confirmer ce problème: j'ai essayé de l'exécuter avec Kaspersky Anti-Virus activé. Mais, quand je l'ai éteint cela fonctionne très bien.

+0

Je me doutais de quelque chose comme ça ... ressemble à un bug dans Kaspersky –

+0

FYI: J'ai Kasperskey (v6.0.4.1424a) et ça marche très bien pour moi avec elle allumé. –

+0

@Troy - Votre configuration Kasperskey est-elle destinée à surveiller les réseaux? Le mien est (configuré par notre administrateur pour surveiller le port 8000, entre autres). –

Questions connexes