Why does this TLS code only runs in debugging mode?
I'm getting a strange error:
The handshake failed due to an unexpected packet format
if I directly run my code without debugging.
And If I set a break point and then debug the code line by line it works fine.
Here is the detail exception
The handshake failed due to an unexpected packet format.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at Searock_IM.Facebook.LoginForm.StartTls() in D:\Projects\Searock IM\Facebook\LoginForm.cs:line 456
at Searock_IM.Facebook.LoginForm.button2_Click(Object sender, EventArgs e) in D:\Projects\Searock IM\Facebook\LoginForm.cs:line 137
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Searock_IM.Program.Main() in D:\Projects\Searock IM\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
and here is the code:
class Connection : IDisposable
{
private readonly Socket _socket;
private NetworkStream _networkStream;
private SslStream _sslStream;
private int _bufferStartIndex;
private readonly byte[] _buffer = new byte[0x8000];
private StringBuilder _recievedText = new StringBuilder();
public StringBuilder Debug { get; private set; }
public bool UseS开发者_JAVA技巧ecure { get; set; }
public void StartTls()
{
UseSecure = true;
if (_networkStream == null)
_networkStream = new NetworkStream( _socket );
if (_sslStream != null)
return;
_sslStream = new SslStream(_networkStream);
_sslStream.AuthenticateAsClient("chat.facebook.com");
lock (Debug)
Debug.AppendFormat( "** Started TLS **<br/>" );
}
public Connection()
{
Debug = new StringBuilder();
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect("chat.facebook.com", 5222);
}
public void Dispose()
{
if (_sslStream != null)
_sslStream.Dispose();
if (_networkStream != null)
_networkStream.Dispose();
}
public void Send(string text)
{
if (String.IsNullOrEmpty( text ))
return;
lock (Debug)
Debug.AppendFormat( "Out: {0} <br/>", HttpUtility.HtmlEncode(text) );
byte[] outp = Encoding.UTF8.GetBytes(text);
if (UseSecure)
_sslStream.Write(outp);
else
_socket.Send(outp);
}
public string Recieve()
{
if (_socket.Available == 0)
return null;
int bytesRead = 0;
if (UseSecure)
bytesRead = _sslStream.Read(_buffer, _bufferStartIndex, _buffer.Length - _bufferStartIndex);
else
bytesRead = _socket.Receive(_buffer, _bufferStartIndex, _buffer.Length - _bufferStartIndex, SocketFlags.None);
ReadBytes( bytesRead );
var incomming = ClearStringBuffer();
lock (Debug)
Debug.AppendFormat( "In: {0}<br/> ", HttpUtility.HtmlEncode( incomming ));
return incomming;
}
private void ReadBytes( int bytesRead )
{
// http://en.wikipedia.org/wiki/UTF-8#Design
// Top 2 bits are either;
// 00xx xxxx => 6 bit ASCII mapped character
// 11xx xxxx => multi byte chatacter Start
// 10xx xxxx => multi byte chatacter Middle of definition
// So while last character in buffer is 'middle of definition' rewind end buffer pointer
int endOfBuffer = bytesRead + _bufferStartIndex;
if (endOfBuffer == 0)
return;
int end = endOfBuffer;
while ((_buffer[end - 1] & 0xC0) == 0x80) --end;
string part = Encoding.UTF8.GetString( _buffer, 0, end ).TrimEnd( '\0' );
if (end != endOfBuffer)
{
_bufferStartIndex = endOfBuffer - end;
for (int i = 0; i < _bufferStartIndex; i++)
_buffer[i] = _buffer[i + end];
}
lock (_recievedText)
_recievedText.Append( part );
}
private string ClearStringBuffer()
{
string result;
lock (_recievedText)
{
result = _recievedText.ToString();
_recievedText = new StringBuilder();
}
return result;
}
}
I get the error The handshake failed due to an unexpected packet format at line:
_sslStream.AuthenticateAsClient("chat.facebook.com");
I'm calling this class from a windows form and I haven't used any threads in this form.
Can someone point me in a right direction? Thanks.
Is it possible that http://chat.facebook.com:5222 does not require a secure connection? See this Facebook help article.
if you telnet to that address and send some dummy data you will get an xml response as
<?xml version="1.0"?>
<stream:stream id="none" from="chat.facebook.com" version="1.0" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams">
<stream:error>
<xml-not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/>
</stream:error>
精彩评论