public void SendFileThread(object obj)
        {
            ByteStreamQueryIQ bsiq = obj as ByteStreamQueryIQ;

            /// Attempt to open our hosts
            ///
            StreamHost host = bsiq.ByteStreamQuery.StreamHostUsed;

            SocketServer.SocketClient client = new SocketClient();

            client.SetSOCKSProxy(5, XMPPClient.Server, 7777, "xmppclient");
            client.OnAsyncConnectFinished += new DelegateConnectFinish(client_OnAsyncConnectFinished);
            EventConnected.Reset();
            ConnectSuccesful = false;

            string strHost = string.Format("{0}{1}{2}", this.FileTransfer.sid, XMPPClient.JID, bsiq.From);
            System.Security.Cryptography.SHA1Managed sha = new System.Security.Cryptography.SHA1Managed();
            byte [] bBytes = sha.ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(strHost));
            strHost = SocketServer.TLS.ByteHelper.HexStringFromByte(bBytes, false, int.MaxValue).ToLower();

            /// Connect parametrs are the sha1 hash and 0, the socks proxy will connect us to the correct place
            client.ConnectAsync(strHost, 0);

            EventConnected.WaitOne();
            if (ConnectSuccesful == true)
            {

                /// Now we must activate the proxy so we can send
                ///
                EventActivate.Reset();
                IQActivate = new ByteStreamQueryIQ();
                IQActivate.ByteStreamQuery = new ByteStreamQuery();
                IQActivate.ByteStreamQuery.SID = this.FileTransfer.sid;
                IQActivate.From = XMPPClient.JID;
                IQActivate.To = host.Jid;
                IQActivate.Type = IQType.set.ToString();
                IQActivate.ByteStreamQuery.Activate = FileTransfer.RemoteJID;
                XMPPClient.SendObject(IQActivate);
                EventActivate.WaitOne();

                if (IsCompleted == true)
                {
                    /// Error, exit this thread
                    FileTransfer.FileTransferState = FileTransferState.Error;
                    XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer);
                    return;
                }

                FileTransfer.BytesRemaining = FileTransfer.Bytes.Length;
                FileTransfer.FileTransferState = FileTransferState.Transferring;

                /// Now send all our data
                ///
                ByteBuffer buffer = new ByteBuffer();
                buffer.AppendData(FileTransfer.Bytes);

                while (buffer.Size > 0)
                {
                    int nSize = (buffer.Size > 16384) ? 16384 : buffer.Size;
                    Sockets.SocketAsyncEventArgs asyncsend = new Sockets.SocketAsyncEventArgs();
                    asyncsend.SetBuffer(buffer.GetNSamples(nSize), 0, nSize);
                    asyncsend.Completed += new EventHandler<Sockets.SocketAsyncEventArgs>(asyncsend_Completed);

                    SendCompletedEvent.Reset();
                    bSendSuccess = false;
                    bool bSent = false;
                    try
                    {
                        client.socket.SendAsync(asyncsend);
                    }
                    catch (Exception ex)
                    {
                        IsCompleted = true;
                        FileTransfer.Error = ex.Message;
                        FileTransfer.FileTransferState = FileTransferState.Error;
                        return;
                    }
                    SendCompletedEvent.WaitOne();
                    if (IsCompleted == true)
                        break;

                    if ((bSendSuccess == false) && (bSent == false) ) /// was sent async because bSent is false, so we can examine bSendSuccess to make sure we sent the right number of bytes
                    {
                        break;
                    }
                    FileTransfer.BytesRemaining -= nSize;
                }

                client.Disconnect();

                FileTransfer.FileTransferState = FileTransferState.Done;
                IsCompleted = true;
                XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer);
                return;
            }

            FileTransfer.Error = "Failed to send data";
            FileTransfer.FileTransferState = FileTransferState.Error;
            IsCompleted = true;
        }
        public void DownloadThread(object obj)
        {
            ByteStreamQueryIQ bsiq = obj as ByteStreamQueryIQ;

            /// Attempt to open our hosts
            ///
            foreach (StreamHost host in bsiq.ByteStreamQuery.Hosts)
            {
                if (IsCompleted == true)
                    break;

                SocketServer.SocketClient client = new SocketClient();

                client.SetSOCKSProxy(5, host.Host, Convert.ToInt32(host.Port), "xmppclient");
                client.OnAsyncConnectFinished += new DelegateConnectFinish(client_OnAsyncConnectFinished);
                EventConnected.Reset();
                ConnectSuccesful = false;

                string strHost = string.Format("{0}{1}{2}", this.FileTransfer.sid, bsiq.From, bsiq.To);
                System.Security.Cryptography.SHA1Managed sha = new System.Security.Cryptography.SHA1Managed();
                byte [] bBytes = sha.ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(strHost));
                strHost = SocketServer.TLS.ByteHelper.HexStringFromByte(bBytes, false, int.MaxValue).ToLower();

                /// Connect parametrs are the sha1 hash and 0, the socks proxy will connect us to the correct place
                client.StartReadOnConnect = true;
                client.ConnectAsync(strHost, 0);

                EventConnected.WaitOne();

                if (ConnectSuccesful == true)
                {
                    FileTransfer.FileTransferState = FileTransferState.Transferring;
                    client.OnReceiveMessage += new SocketClient.SocketReceiveHandler(client_OnReceiveMessage);
                    DownloadFileBuffer.GetAllSamples();

                    /// connected and negotiated socks5, tell the far end to start sending data
                    ///
                    ByteStreamQueryIQ iqresponse = new ByteStreamQueryIQ();
                    iqresponse.SID = this.FileTransfer.sid;
                    iqresponse.ByteStreamQuery = new ByteStreamQuery();
                    iqresponse.ByteStreamQuery.StreamHostUsed = new StreamHost();
                    iqresponse.ByteStreamQuery.StreamHostUsed.Jid = host.Jid;
                    iqresponse.From = XMPPClient.JID;
                    iqresponse.ID = bsiq.ID;
                    iqresponse.To = bsiq.From;
                    iqresponse.Type = IQType.result.ToString();
                    XMPPClient.SendObject(iqresponse);

                    /// Now read data until we get our desired amount
                    ///
                    EventGotAllData.WaitOne();

                    client.Disconnect();
                    return;
                }
            }

            /// Couldn't transfer file, send error
            ///
            ByteStreamQueryIQ response = new ByteStreamQueryIQ();
            response.ByteStreamQuery = bsiq.ByteStreamQuery;
            response.From = XMPPClient.JID;
            response.To = bsiq.From;
            response.ID = bsiq.ID;
            response.Type = IQType.error.ToString();
            response.Error = new Error(ErrorType.remoteservertimeout);
            XMPPClient.SendXMPP(response);
            FileTransfer.Error = "Could not connect to proxy";
            FileTransfer.FileTransferState = FileTransferState.Error;
            XMPPClient.FileTransferManager.FinishActiveFileTransfer(FileTransfer);
        }