2009-12-05 6 views
4

J'ai essayé d'écrire un script qui reniflera les en-têtes HTTP. Jusqu'à présent, j'ai le socket lié au port 80 et les paquets semblent être reçus, mais je ne peux pas les obtenir en forme de chaîne. Tout ce qui sort est "E" en continu. J'ai changé les octets en hex plus tôt et il semble y avoir des données qui arrivent, mais le code actuel est incapable de changer les octets en une chaîne. Existe-t-il un autre moyen de décoder les octets qui donneront une chaîne correcte?C# Obtention de données par paquets

byte[] input = BitConverter.GetBytes(1); 
byte[] buffer = new byte[4096]; 
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
s.Bind(new IPEndPoint(IPAddress.Parse(strIP), 80)); 
s.IOControl(IOControlCode.ReceiveAll, input, null); 
int bytes; 
bytes = s.Receive(buffer); 
while (bytes > 0) 
{ 
    log(System.Text.Encoding.ASCII.GetString(buffer, 0, bytes)); 
    bytes = s.Receive(buffer); 
} 

Répondre

6

Lorsque vous renifler des données en utilisant une prise premières , vous recevez des paquets IP (Internet Protocol). Chaque paquet IP commence par IP header. Cet en-tête a généralement une longueur de 20 octets, mais il peut être plus long que cela. Après l'en-tête IP est l'en-tête pour la couche de transport, par exemple, l'en-tête Transmission Control Protocol (TCP) ou l'en-tête User Datagram Protocol (UDP). Après cet en-tête, vous obtenez les données que vous recherchez, c'est-à-dire le HTTP. Ainsi, lorsque vous analysez les données, vous devez d'abord ignorer l'en-tête IP et l'en-tête Transport Layer.

+0

'Comment' aurait été intéressant ... – C4u

5

Vous pouvez extraira le code source de ce réseau C# renifleur, here.

+0

Merci, j'ai jeté un coup d'oeil à ceci mais je pense qu'il renvoie juste les données comme tableau d'octets, pas comme chaîne. Les données de l'en-tête sont-elles susceptibles de provoquer un problème de conversion en chaîne? – James

5

Tout d'abord, pourquoi est-ce que vous écrivez ceci en utilisant des sockets raw et en changeant le IOControl? J'ai essayé d'exécuter votre code sur Vista et cela ne fonctionnerait pas, même en tant qu'administrateur. Pouvez-vous utiliser un niveau d'abstraction plus élevé, tel que TcpClient à la place?

Deuxièmement, vous devez envoyer une demande avant d'obtenir une réponse. La requête la plus simple que vous pouvez envoyer est "GET/\ n" où \ n est le caractère d'une nouvelle ligne.

Voici un code que vous pouvez utiliser (la méthode Write doit vérifier la valeur de retour aussi, mais cela est omis pour simplifier):

 using (TcpClient tcpClient = new TcpClient(strIP, 80)) 
     { 
      using (Stream s = tcpClient.GetStream()) 
      { 
       byte[] bytesToSend = Encoding.ASCII.GetBytes("GET /\n"); 
       s.Write(bytesToSend, 0, bytesToSend.Length); 
       int bytes; 
       byte[] buffer = new byte[4096]; 
       do 
       { 
        bytes = s.Read(buffer, 0, buffer.Length); 
        Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes)); 
       } while (bytes > 0); 
      } 
     }