我得到一個奇怪的錯誤:爲什麼此TLS代碼只能在調試模式下運行?
The handshake failed due to an unexpected packet format
,如果我的情況下直接調試運行我的代碼。
而且,如果我設置了一個斷點,然後逐行調試代碼,它的工作正常。
下面是詳細的異常
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()
這裏是代碼:
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 UseSecure { 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;
}
}
我得到錯誤的握手在行失敗,因爲一個意外的數據包格式:
_sslStream.AuthenticateAsClient("chat.facebook.com");
我從窗體窗體調用這個類,我沒有使用這種形式的任何線程。
有人可以指出我正確的方向嗎?謝謝。
? [請幫幫忙](http://code.google.com/p/jabber-net/)。 –
否則,不要相信來自Facebook的文檔;它可能都是關閉的。瞭解如何實現它(來自真實來源)(http://xmpp.org/xmpp-protocols/rfcs/),但它確實不是微不足道的 - 您可以花費3個月時間實現完整的堆棧,真的,只需要用jabber-net。 –
@Jonathan Dickinson出於學習目的。它不像我的代碼根本不工作,但只是一個奇怪的錯誤。 – Searock