コード例 #1
0
        protected void KickCompleted(SocketAsyncEventArgsExt argz)
        {
            try
            {
                if (argz.SocketError == SocketError.Success)
                {
                    if (argz.LastOperation == SocketAsyncOperation.Disconnect)
                    {
                        kickPool.Put(argz);
                        HandleError(SocketError.Disconnecting);
                    }
                    else
                    {
                        if (!socket.DisconnectAsync(argz))
                        {
                            kickPool.Put(argz);
                            HandleError(SocketError.Disconnecting);
                        }
                    }
                }
                else
                {
                    HandleError(argz.SocketError);
                    kickPool.Put(argz);
                }

//				kicking = false;
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception in connection disconnect callback");
            }
        }
コード例 #2
0
        protected void SendCompleted(SocketAsyncEventArgsExt argz)
        {
            try
            {
                MessageSendCompleted();
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception in connection send callback");
            }

            try
            {
                //ProgramLog.Debug.Log ("SendCompleted {");
                if (argz.SocketError != SocketError.Success)
                {
                    HandleError(argz.SocketError);
                    sendPool.Put(argz);
                }
                else
                {
                    lock (sendQueue)
                    {
//						if (kicking)
//						{
//							sendPool.Put (argz);
//							sending = false;
//							return;
//						}

                        TxListClear();

                        sending = SendMore(argz);
                        if (!sending && argz.conn != null)
                        {
                            sendPool.Put(argz);
                        }
                    }
                }
                //ProgramLog.Debug.Log ("} SendCompleted " + sending);
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception in connection send callback");
            }
        }
コード例 #3
0
            public void Put(SocketAsyncEventArgsExt args)
            {
                //              ProgramLog.Debug.Log ("Put");
                if (!(args is T))
                {
                    ProgramLog.Error.Log("ArgsPool type mismatch.");
                    return;
                }

                lock (this)
                {
                    if (args.conn == null)
                    {
                        ProgramLog.Error.Log("{0} freed twice.", typeof(T).Name);
                        return;
                    }

                    args.BufferList = null;

                    args.conn = null;

                    Push((T)args);
                }
            }
コード例 #4
0
        protected void KickCompleted(SocketAsyncEventArgsExt argz)
        {
            try
            {
                if (argz.SocketError == SocketError.Success)
                {
                    if (argz.LastOperation == SocketAsyncOperation.Disconnect)
                    {
                        kickPool.Put(argz);
                        HandleError(SocketError.Disconnecting);
                    }
                    else
                    {
                        if (!socket.DisconnectAsync(argz))
                        {
                            kickPool.Put(argz);
                            HandleError(SocketError.Disconnecting);
                        }
                    }
                }
                else
                {
                    HandleError(argz.SocketError);
                    kickPool.Put(argz);
                }

                //              kicking = false;
            }
            catch (ObjectDisposedException)
            {
            }
            catch (Exception e)
            {
                Tools.WriteLine("Exception in connection disconnect callback: {0}", e);
            }
        }
コード例 #5
0
        protected void ReceiveCompleted(SocketAsyncEventArgsExt argz)
        {
            try
            {
                if (argz.SocketError != SocketError.Success)
                {
                    //ProgramLog.Debug.Log ("Bytes received: {0}", argz.BytesTransferred);
                    var err = argz.SocketError;
                    receiving = false;
                    recvPool.Put(argz);
                    HandleError(err);
                }
                else if (argz.BytesTransferred == 0)
                {
                    //ProgramLog.Debug.Log ("Clean connection shutdown. {0}", socket.Connected);
                    receiving = false;
                    recvPool.Put(argz);
                    HandleError(SocketError.Disconnecting);
                }
                else
                {
                    var bytes = argz.BytesTransferred;
                    receiving = false;

                    if (kicking)
                    {
                        recvPool.Put(argz);
                        return;
                    }

                    while (!receiving)
                    {
                        recvBytes     += bytes;
                        BytesReceived += bytes;

                        ProcessRead();

                        if (kicking)
                        {
                            receiving = false;
                            break;
                        }

                        var left = recvBuffer.Length - recvBytes;

                        if (left <= 0)
                        {
                            return;
                        }

                        argz.SetBuffer(recvBuffer, recvBytes, left);
                        try
                        {
                            receiving = socket.ReceiveAsync(argz);
                        }
                        catch (ObjectDisposedException)
                        {
                            receiving = false;
                        }

                        if (receiving)
                        {
                            bytes = argz.BytesTransferred;
                        }
                    }

                    if (!receiving)
                    {
                        recvPool.Put(argz);
                    }
                }
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception in connection receive callback");
            }
        }
コード例 #6
0
        //#if BANDWIDTH_ANALYSIS
        //      public static int[] packetsPerMessage = new int [255];
        //      public static long[] bytesPerMessage = new long [255];
        //#endif

        protected bool SendMore(SocketAsyncEventArgsExt args, bool flush = false)
        {
            flush |= txBuffer == null;

            try
            {
                var queued = false;
                var escape = false;

                while (sendQueue.Count > 0 && txListBytes < 2880 && !escape)
                {
                    var msg = sendQueue.PopFront();

                    switch (msg.kind)
                    {
                    case Message.BYTES:
                    {
                        var data = (byte[])msg.content;
                        txList.Add(new ArraySegment <byte>(data));
                        txListBytes += data.Length;
                        queueSize   -= data.Length + ARRAY_OBJECT_OVERHEAD;
                        //ProgramLog.Debug.Log ("{1}: Adding bytes {0}", data.Length, Thread.CurrentThread.IsThreadPoolThread);
                        break;
                    }

                    case Message.SEGMENT:
                    {
                        var len        = msg.param;
                        var txc        = txList.Count;
                        int wraparound = 0;

                        if (txc > 0 && txList[txc - 1].Array == txBuffer)
                        {
                            var seg  = txList[txc - 1];
                            var nlen = seg.Count + len;
                            var nseg = new ArraySegment <byte>(txBuffer, seg.Offset, Math.Min(nlen, txBuffer.Length - seg.Offset));

                            //ProgramLog.Debug.Log ("{5}: Coalescing {0}, {1} and {2}, {3} [{4}]", seg.Offset, seg.Count, (txHead + txPrepared) % txBuffer.Length, len, nseg.Count, Thread.CurrentThread.IsThreadPoolThread);

                            txList[txc - 1] = nseg;

                            wraparound = nlen - nseg.Count;
                        }
                        else
                        {
                            var offset = (txHead + txPrepared) % txBuffer.Length;

                            //ProgramLog.Debug.Log ("{2}: Adding segment {0}, {1}", offset, len, Thread.CurrentThread.IsThreadPoolThread);

                            var nseg = new ArraySegment <byte>(txBuffer, offset, Math.Min(len, txBuffer.Length - offset));
                            txList.Add(nseg);

                            wraparound = len - nseg.Count;
                        }

                        if (wraparound > 0)
                        {
                            txList.Add(new ArraySegment <byte>(txBuffer, 0, wraparound));
                        }

                        txPrepared  += len;
                        txListBytes += len;
                        queueSize   -= len;

                        break;
                    }

                    default:
                    {
                        var data = SerializeMessage(msg);
                        txList.Add(data);
                        txListBytes += data.Count;
                        //ProgramLog.Debug.Log ("{1}: Adding custom {0}", data.Count, Thread.CurrentThread.IsThreadPoolThread);
                        escape = true;
                        break;
                    }

                    case Message.KICK:
                    {
                        if ((!queued) /*&& (! sending)*/ && args != null && args.conn != null)
                        {
                            sendPool.Put(args);
                        }

                        //txList.Clear ();
                        //txListBytes = 0;

                        var kickArgs = kickPool.Take(this);

                        var data = (byte[])msg.content;
                        kickArgs.SetBuffer(data, 0, data.Length);
                        if (!socket.SendAsync(kickArgs))
                        {
                            if (!socket.DisconnectAsync(kickArgs))
                            {
                                KickCompleted(kickArgs);
                            }
                        }

                        return(false);
                    }
                    }
                }

                if (escape)
                {
                    flush = true;
                }

                if (txListBytes >= 1450 || (txListBytes > 0 && flush))
                {
                    if (args == null)
                    {
                        args = sendPool.Take(this);
                    }

                    if (txList.Count > 1)
                    {
                        args.SetBuffer(null, 0, 0);
                        args.BufferList = txList;
                    }
                    else
                    {
                        var seg = txList[0];
                        args.BufferList = null;
                        args.SetBuffer(seg.Array, seg.Offset, seg.Count);
                    }

                    //                  var o = 0;
                    //                  for (int i = 0; i < txList.Count; i++)
                    //                      o += 40 * (1 + txList[i].Count / 1460) + txList[i].Count;
                    //
                    var n = 40 * (1 + txListBytes / 1460) + txListBytes;
                    //                  Interlocked.Add (ref totalBytesBuffered, (long)n);
                    //                  Interlocked.Add (ref totalBytesUnbuffered, (long)o);

                    BytesSent += n;

                    try
                    {
                        queued = socket.SendAsync(args);
                    }
                    finally
                    {
                        if (!queued)
                        {
                            TxListClear();
                            if (escape)
                            {
                                MessageSendCompleted();
                            }
                        }
                    }
                }

                return(queued);
            }
            catch (SocketException e)
            {
                HandleError(e.SocketErrorCode);
            }
            catch (ObjectDisposedException)
            {
                HandleError(SocketError.OperationAborted);
            }

            return(false);
        }
コード例 #7
0
 private void ProcessConnectCompleted(bool synchronous)
 {
     this.sendArgs.Completed -= this.OnTcpConnectCompleted;
     if (this.sendArgs.SocketError == SocketError.Success)
     {
         this.receiveArgs = new SocketAsyncEventArgsExt();
         this.receiveArgs.Completed += this.OnReceiveCompleted;
         this.sendArgs.Completed -= this.OnTcpConnectCompleted;
         this.sendArgs.Completed += this.OnSendCompleted;
         this.StartWebSocketHandshake(_customHeaders); // this is the entry point to a version specific derived class
     }
     else
     {
         this.FailWebSocketConnection(this.sendArgs.ConnectByNameError, synchronous);
     }
 }
コード例 #8
0
        public void Start(Dictionary<string, string> customHeaders)
        {
            if (customHeaders != null)
                this._customHeaders = customHeaders;

            this.sendArgs = new SocketAsyncEventArgsExt();
            this.sendArgs.RemoteEndPoint = new DnsEndPoint(this.Uri.DnsSafeHost, this.Uri.Port);
            #if !SILVERLIGHT
            #else
            this.sendArgs.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http;
            #endif
            this.sendArgs.Completed += this.OnTcpConnectCompleted;
            this.socket = new SecureSocketProxy("wss".Equals(Uri.Scheme, StringComparison.OrdinalIgnoreCase));
            this.socket.NoDelay = this.noDelay;

            if (!this.socket.ConnectAsync(this.sendArgs))
            {
                this.ProcessConnectCompleted(true);
            }
        }
コード例 #9
0
        /// <summary>
        /// Begins an asynchronous read operation that reads data from the stream and stores 
        /// it in the specified array.
        /// </summary>
        /// <param name="args">A user-defined object that contains information about the read 
        /// operation. This object is passed to the asyncCallback delegate when the operation 
        /// completes.</param>
        /// <returns>Return true if state of receive is success.</returns>
        public bool ReceiveAsync(SocketAsyncEventArgsExt args)
        {
            if (_isSecure)
            {
                _sslStream.BeginRead(args.Buffer, args.Offset, args.Count, ReceiveComplete, args);
                return true;
            }

            return _socket.ReceiveAsync(args);
        }