Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Diagnostics;
- using System.IO;
- using System.Net;
- using System.Net.Security;
- using System.Net.Sockets;
- using System.Security.Authentication;
- using System.Text;
- using System.Threading;
- namespace DeriveClassNameSpace.Services.Web
- {
- public class TcpMessaging
- {
- public const int HttpCodepage = 28591;
- public static readonly Encoding HttpEncoding = Encoding.GetEncoding( HttpCodepage );
- private static readonly string divider = new string( '-', 20 );
- private static readonly string simpleGet =
- @"GET / HTTP/1.0
- Host: {0}
- Content-Length: -1
- Connection: Keep-Alive
- Authorization: Basic {1}
- ";
- public static void TestViaTcp( IPEndPoint endpoint, string auth, bool useSSL )
- {
- if (endpoint != null)
- {
- Console.WriteLine( "Connecting..." );
- using (TcpClient request = new TcpClient())
- {
- request.Connect( endpoint );
- Console.WriteLine( String.Format( "Connection made from {0} to {1}", request.Client.LocalEndPoint, endpoint ) );
- using (NetworkStream tcpStream = request.GetStream())
- {
- TcpMessageState state = null;
- try
- {
- string host = endpoint.Address.ToString();
- if (useSSL)
- {
- RemoteCertificateValidationCallback callback =
- new RemoteCertificateValidationCallback( Program.ValidateServerCertificate );
- SslProtocols protocol = SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls;
- using (SslStream secureStream = new SslStream( tcpStream, false, callback ))
- {
- secureStream.AuthenticateAsClient( endpoint.ToString(), null, protocol, false );
- RequestResponse( secureStream, host, auth, ref state );
- }
- }
- else
- {
- RequestResponse( tcpStream, host, auth, ref state );
- }
- }
- catch (Exception e)
- {
- Console.WriteLine( "ERROR DURING GET: {0}", e.Message );
- }
- finally
- {
- if (state != null)
- {
- state.Close();
- state = null;
- }
- }
- if (tcpStream != null)
- {
- tcpStream.Close();
- }
- }
- if (request != null)
- {
- request.Close();
- }
- }
- }
- }
- private static void RequestResponse( Stream stream, string host, string auth, ref TcpMessageState state )
- {
- string tcpMsg = String.Format( simpleGet, host, auth );
- byte[] rawMsg = HttpEncoding.GetBytes( tcpMsg );
- Console.WriteLine( "Sending message..." );
- stream.Write( rawMsg, 0, rawMsg.Length );
- stream.Flush();
- state = new TcpMessageState( stream, HttpEncoding );
- Console.WriteLine( "Waiting for response..." );
- IAsyncResult result = state.Stream.BeginRead( state.Buffer, 0, TcpMessageState.BufferSize, new AsyncCallback( ReceiveCallback ), state );
- state.ResponseReceived.WaitOne();
- Console.WriteLine( "Response received:" );
- Console.WriteLine( divider );
- string response = state.Message;
- // Look for the header/body seperator, two 'newline' characters (which are platform dependant)
- int pos1 = response.IndexOf( "\r\n\r\n" );
- int pos2 = response.IndexOf( "\n\n" );
- if (pos1 < 1 && pos2 > 1)
- {
- pos2 += 2;
- pos1 = pos2;
- }
- else if (pos2 < 1 && pos1 > 1)
- {
- pos1 += 4;
- pos2 = pos1;
- }
- else
- {
- pos1 += 4;
- pos2 += 2;
- }
- int pos = Math.Min( pos1, pos2 );
- if (response.Length > 1024 && pos > 0)
- {
- // Replace the body, I'm only interested in the headers at this point
- response = response.Substring( 0, pos ) + String.Format( "<body of {0} characters removed>", response.Length - pos );
- }
- Console.WriteLine( response );
- Console.WriteLine( divider );
- }
- private static void ReceiveCallback( IAsyncResult ar )
- {
- try
- {
- TcpMessageState state = ar.AsyncState as TcpMessageState;
- if (state == null)
- {
- Debug.WriteLine( String.Format( "Did not recieve expected state object! Wanted: {0}, Got: {1}", typeof( TcpMessageState ), ar.AsyncState == null ? "null" : ar.AsyncState.GetType().ToString() ) );
- }
- // Read data from the remote device.
- int bytesRead = state.Stream.EndRead( ar );
- if (bytesRead > 0)
- {
- // There might be more data, so store the data received so far.
- state.AddBufferToMessage( bytesRead );
- // Get the rest of the data.
- state.Stream.BeginRead( state.Buffer, 0, TcpMessageState.BufferSize, new AsyncCallback( ReceiveCallback ), state );
- }
- else
- {
- // Signal that all bytes have been sent.
- state.ResponseReceived.Set();
- }
- }
- catch (Exception e)
- {
- Debug.WriteLine( "ERROR: " + e.Message );
- }
- }
- private void UnreadMessage( TcpClient request )
- {
- // Data to read?
- if (request.Connected && request.Available > 0)
- {
- Console.WriteLine( "TcpClient has a message for us!" );
- Console.WriteLine( divider );
- NetworkStream tcpStream = request.GetStream();
- TcpMessageState state = new TcpMessageState( tcpStream, HttpEncoding );
- int count = tcpStream.Read( state.Buffer, 0, request.Available );
- state.AddBufferToMessage( count );
- Console.WriteLine( String.Format( "Read {0} bytes: {1}", count, state.Message ) );
- Console.WriteLine( divider );
- }
- }
- private class TcpMessageState
- {
- internal const int BufferSize = 2 ^ 11;
- private StringBuilder message = new StringBuilder();
- internal TcpMessageState( Stream stream, Encoding encoding )
- {
- this.ResponseReceived = new AutoResetEvent( false );
- this.Encoding = encoding;
- this.Stream = stream;
- this.Buffer = new byte[BufferSize];
- }
- public AutoResetEvent ResponseReceived
- {
- get;
- private set;
- }
- public string Message
- {
- get
- {
- return this.message.ToString();
- }
- }
- public Encoding Encoding
- {
- get;
- private set;
- }
- public Stream Stream
- {
- get;
- private set;
- }
- public byte[] Buffer
- {
- get;
- private set;
- }
- internal void AddBufferToMessage( int bytesRead )
- {
- this.message.Append( this.Encoding.GetString( this.Buffer, 0, bytesRead ) );
- }
- internal void Close()
- {
- this.Buffer = null;
- this.Encoding = null;
- this.ResponseReceived.Close();
- this.ResponseReceived = null;
- this.Stream.Close();
- this.Stream = null;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement