예제 #1
0
            /// <summary>
            /// try send
            /// </summary>
            /// <param name="packet"></param>
            /// <returns></returns>
            public SendResult TrySend(Packet packet)
            {
                lock (this)
                {
                    if (this._isClosed) return SendResult.Closed;

                    if (this._isSending)
                    {
                        if (this._queue.Count < 5000)
                        {
                            this._queue.Enqueue(packet);
                            return SendResult.Enqueued;
                        }
                        else
                        {
                            Log.Trace.Error("queue full",new Exception("queue full"));
                        }
                    }
                    else
                    {
                        this._isSending = true;
                        return SendResult.SendCurr;
                    }
                }

                Thread.Sleep(1);
                return this.TrySend(packet);
            }
예제 #2
0
 /// <summary>
 /// OnStartSending
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="packet"></param>
 protected virtual void OnStartSending(IConnection connection, Packet packet)
 {
 }
예제 #3
0
        /// <summary>
        /// internal send packet.
        /// </summary>
        /// <param name="packet"></param>
        /// <exception cref="ArgumentNullException">packet is null</exception>
        private void SendPacketInternal(Packet packet)
        {
            var e = this._saeSend;
            var queue = this._sendQueue;
            if (!this.Active || e == null || queue == null)
            {
                this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Failed)); return;
            }

            switch (queue.TrySend(packet))
            {
                case SendResult.Closed:
                    this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Failed)); break;
                case SendResult.SendCurr:
                    this.OnStartSending(packet);
                    this.SendPacketInternal(packet, e);
                    break;
            }
        }
예제 #4
0
        /// <summary>
        /// internal send packet.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="e"></param>
        private void SendPacketInternal(Packet packet, SocketAsyncEventArgs e)
        {
            this._currSendingPacket = packet;

            //按_messageBufferSize大小分块传输
            var length = Math.Min(packet.Payload.Length - packet.SentSize, this._messageBufferSize);

            var completedAsync = true;
            try
            {
                //copy data to send buffer
                Buffer.BlockCopy(packet.Payload, packet.SentSize, e.Buffer, 0, length);
                e.SetBuffer(0, length);
                completedAsync = this._socket.SendAsync(e);
            }
            catch (Exception ex)
            {
                this.BeginDisconnect(ex);
                this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Failed));
                this.OnError(ex);
            }

            if (!completedAsync) this.SendAsyncCompleted(this, e);
        }
예제 #5
0
        /// <summary>
        /// async send callback
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendAsyncCompleted(object sender, SocketAsyncEventArgs e)
        {
            var packet = this._currSendingPacket;
            if (packet == null)
            {
                var ex = new Exception(string.Concat("未知的错误, connection state:",
                    this.Active.ToString(),
                    " conectionID:",
                    this.ConnectionID.ToString(),
                    " remote address:",
                    this.RemoteEndPoint.ToString()));
                this.OnError(ex);
                this.BeginDisconnect(ex);
                return;
            }

            //send error!
            if (e.SocketError != SocketError.Success)
            {
                this.BeginDisconnect(new SocketException((int)e.SocketError));
                this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Failed));
                return;
            }

            packet.SentSize += e.BytesTransferred;

            if (e.Offset + e.BytesTransferred < e.Count)
            {
                //continue to send until all bytes are sent!
                var completedAsync = true;
                try
                {
                    e.SetBuffer(e.Offset + e.BytesTransferred, e.Count - e.BytesTransferred - e.Offset);
                    completedAsync = this._socket.SendAsync(e);
                }
                catch (Exception ex)
                {
                    this.BeginDisconnect(ex);
                    this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Failed));
                    this.OnError(ex);
                }

                if (!completedAsync) this.SendAsyncCompleted(sender, e);
            }
            else
            {
                if (packet.IsSent())
                {
                    this._currSendingPacket = null;
                    this.OnSendCallback(new SendCallbackEventArgs(packet, SendCallbackStatus.Success));

                    //send next packet
                    var queue = this._sendQueue;
                    if (this.Active && queue != null)
                    {
                        Packet nextPacket = queue.TrySendNext();
                        if (nextPacket != null)
                        {
                            this.OnStartSending(nextPacket);
                            this.SendPacketInternal(nextPacket, e);
                        }
                    }
                }
                else this.SendPacketInternal(packet, e);//continue send this packet
            }
        }
예제 #6
0
 /// <summary>
 /// fire StartSending
 /// </summary>
 /// <param name="packet"></param>
 private void OnStartSending(Packet packet)
 {
     if (this.StartSending != null) this.StartSending(this, packet);
 }
예제 #7
0
 /// <summary>
 /// 异步发送数据
 /// </summary>
 /// <param name="packet"></param>
 public void BeginSend(Packet packet)
 {
     this.SendPacketInternal(packet);
 }
예제 #8
0
 public void OnStartSending(IConnection connection, Packet packet)
 {
     //throw new NotImplementedException();
     Console.WriteLine("send beging");
 }
예제 #9
0
 /// <summary>
 /// start sending
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="packet"></param>
 protected override void OnStartSending(IConnection connection, Packet packet)
 {
     base.OnStartSending(connection, packet);
     try { this._handler.OnStartSending(connection, packet); }
     catch (Exception ex) { Log.Trace.Error(ex.Message, ex); }
 }