C # Ottenere dati a pacchetto
-
13-09-2019 - |
Domanda
Ho cercato di scrivere uno script che annusare intestazioni HTTP. Finora ho avuto la presa associato alla porta 80 e i pacchetti sembrano essere ricevuto, ma non riesco a entrare in forma di stringa. Tutto che emette è "E" continuamente. Ho cambiato il byte in esadecimale prima e sembra che ci sia alcuni dati in arrivo, ma il codice corrente non è in grado di cambiare i byte in una stringa. C'è qualche altro modo di decodificare i byte che darà una stringa corretta?
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);
}
Soluzione
Quando si annusa dati utilizzando un pacchetto raw presa, si sta ricevendo Internet Protocol (IP). Ogni pacchetto IP inizia con un IP intestazione . Questo collettore è tipicamente lungo 20 byte, ma può essere più lungo di quello. Di seguito l'intestazione IP è l'intestazione per il livello di trasporto, ad esempio, il Transmission Control Protocol (TCP) intestazione o il User Datagram Protocol intestazione (UDP). Dopo questa intestazione segue i dati che stai cercando, vale a dire, l'HTTP. Così, quando sei l'analisi dei dati, è necessario passare oltre l'intestazione IP e l'intestazione Transport Layer prima.
Altri suggerimenti
Si potrebbe desiderare di checkout il codice sorgente di questo C # sniffer di rete, qui .
In primo luogo, il motivo per cui stai scrivendo questo utilizzando socket raw e cambiando l'IOControl? Ho provato a fare funzionare il codice su Vista e che non avrebbe funzionato, anche come amministratore. Si può utilizzare un più alto livello di astrazione, come ad esempio TcpClient, invece?
In secondo luogo, è necessario inviare una richiesta prima di ottenere una risposta. La richiesta più semplice è possibile inviare è "GET / \ n", dove \ n è il carattere per una nuova linea.
Ecco un codice che è possibile utilizzare (il metodo di scrittura ha bisogno di controllare il valore di ritorno troppo, ma questo è omesso per semplicità):
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);
}
}