コード例 #1
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        private void ProcessSend(SocketAsyncEventArgs ioEventArgs)
        {
            DataToken dataToken = (DataToken)ioEventArgs.UserToken;

            if (ioEventArgs.SocketError == SocketError.Success)
            {
                dataToken.messageBytesDone += ioEventArgs.BytesTransferred;
                if (dataToken.messageBytesDone != dataToken.messageLength)
                {
                    PostSend(ioEventArgs);
                }
                else
                {
                    dataToken.ResultCallback(ResultCode.Success);
                    dataToken.Reset(true);
                    try
                    {
                        TryDequeueAndPostSend(dataToken.Socket, ioEventArgs);
                    }
                    catch
                    {
                        dataToken.Socket.ResetSendFlag();
                        throw;
                    }
                }
            }
            else
            {
                dataToken.ResultCallback(ResultCode.Close);
                dataToken.Socket.ResetSendFlag();
                Closing(ioEventArgs);
            }
        }
コード例 #2
0
ファイル: PrefixHandler.cs プロジェクト: 87170360/Maximus
        public int HandlePrefix(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
        {
            if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone)
            {
                for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.DataOffset + i];
                }
                remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone;
                dataToken.bufferSkip += 4 - dataToken.prefixBytesDone;
                dataToken.prefixBytesDone = 4;
                dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0);
            }
            else
            {
                for (int i = 0; i < remainingBytesToProcess; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.DataOffset + i];
                }
                dataToken.prefixBytesDone += remainingBytesToProcess;
                remainingBytesToProcess = 0;
            }

            return remainingBytesToProcess;
        }
コード例 #3
0
ファイル: MessageHandler.cs プロジェクト: zhukaixy/Scut
        public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
        {
            if (dataToken.messageBytesDone == 0)
            {
                dataToken.byteArrayForMessage = new byte[dataToken.messageLength];
            }

            var nonCopiedBytes = 0;

            if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength)
            {
                var copyedBytes = dataToken.RemainByte;
                nonCopiedBytes = remainingBytesToProcess - copyedBytes;
                Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes);
                dataToken.messageBytesDone = dataToken.messageLength;
                dataToken.bufferSkip      += copyedBytes;
            }
            else
            {
                Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess);
                dataToken.messageBytesDone += remainingBytesToProcess;
            }

            return(nonCopiedBytes);
        }
コード例 #4
0
ファイル: ClientSocket.cs プロジェクト: suncle/Scut
        /// <summary>
        /// Connect this instance.
        /// </summary>
        public void Connect()
        {
            socket = new Socket(this.clientSettings.RemoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(this.clientSettings.RemoteEndPoint);
            connected = true;

            var buffer = new byte[this.clientSettings.BufferSize * 2];

            this.sendEventArg = new SocketAsyncEventArgs();
            this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize);
            this.sendDataToken = new DataToken();
            this.sendDataToken.bufferOffset = this.sendEventArg.Offset;
            this.sendEventArg.UserToken     = this.sendDataToken;
            this.sendEventArg.AcceptSocket  = socket;
            this.sendEventArg.Completed    += new EventHandler <SocketAsyncEventArgs>(IO_Completed);

            this.receiveEventArg = new SocketAsyncEventArgs();
            this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize);
            this.receiveDataToken = new DataToken();
            this.receiveDataToken.bufferOffset = this.receiveEventArg.Offset;
            this.receiveEventArg.UserToken     = this.receiveDataToken;
            this.receiveEventArg.AcceptSocket  = socket;
            this.receiveEventArg.Completed    += new EventHandler <SocketAsyncEventArgs>(IO_Completed);

            PostReceive();
        }
コード例 #5
0
ファイル: PrefixHandler.cs プロジェクト: dongliang/Scut
        public int HandlePrefix(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
        {
            if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone)
            {
                for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.dataOffset + i];
                }
                remainingBytesToProcess   = remainingBytesToProcess - 4 + dataToken.prefixBytesDone;
                dataToken.bufferSkip     += 4 - dataToken.prefixBytesDone;
                dataToken.prefixBytesDone = 4;
                dataToken.messageLength   = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0);
            }
            else
            {
                for (int i = 0; i < remainingBytesToProcess; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.dataOffset + i];
                }
                dataToken.prefixBytesDone += remainingBytesToProcess;
                remainingBytesToProcess    = 0;
            }

            return(remainingBytesToProcess);
        }
コード例 #6
0
        private bool StartProcessSend(SocketAsyncEventArgs e)
        {
            try
            {
                DataToken session = e.UserToken as DataToken;
                if (session.messageLength - session.messageBytesDone <= _bufferSize)
                {
                    e.SetBuffer(session.bufferOffset, session.messageLength - session.messageBytesDone);
                    Buffer.BlockCopy(session.byteArrayForMessage, session.messageBytesDone, e.Buffer, session.bufferOffset, session.messageLength - session.messageBytesDone);
                }
                else
                {
                    e.SetBuffer(session.bufferOffset, _bufferSize);
                    Buffer.BlockCopy(session.byteArrayForMessage, session.messageBytesDone, e.Buffer, session.bufferOffset, _bufferSize);
                }

                bool willRaiseEvent = true;
                willRaiseEvent = e.AcceptSocket.SendAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessSend(e);
                }
                return(true);
            }
            catch (Exception ex)
            {
                TraceLog.WriteError("TryProcessSend:{0}", ex);
            }
            return(false);
        }
コード例 #7
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        private void IO_Completed(object sender, SocketAsyncEventArgs ioEventArgs)
        {
            DataToken ioDataToken = (DataToken)ioEventArgs.UserToken;

            try
            {
                ioDataToken.Socket.LastAccessTime = DateTime.Now;
                switch (ioEventArgs.LastOperation)
                {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(ioEventArgs);
                    break;

                case SocketAsyncOperation.Send:
                    ProcessSend(ioEventArgs);
                    break;

                default:
                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
                }
            }
            catch (ObjectDisposedException)
            {
                //modify disposed error ignore log
                //logger.Error(string.Format("IO_Completed error:{0}", error));
                ReleaseIOEventArgs(ioEventArgs);
            }
            catch (Exception ex)
            {
                logger.Error(string.Format("IP {0} IO_Completed unkown error:{1}", (ioDataToken != null && ioDataToken.Socket != null ? ioDataToken.Socket.RemoteEndPoint.ToNotNullString() : ""), ex));
            }
        }
コード例 #8
0
        private int HandlePrefix(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess)
        {
            if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone)
            {
                for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i];
                }
                remainingBytesToProcess   = remainingBytesToProcess - 4 + dataToken.prefixBytesDone;
                dataToken.bufferSkip     += 4 - dataToken.prefixBytesDone;
                dataToken.prefixBytesDone = 4;
                dataToken.messageLength   = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0);
            }
            else
            {
                for (int i = 0; i < remainingBytesToProcess; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i];
                }
                dataToken.prefixBytesDone += remainingBytesToProcess;
                remainingBytesToProcess    = 0;
            }

            return(remainingBytesToProcess);
        }
コード例 #9
0
        private void Bind(Socket acceptSocket)
        {
            var exSocket = new ExSocket(acceptSocket);

            exSocket.LastAccessTime = DateTime.Now;
            var buffer = new byte[this.clientSettings.BufferSize * 2];

            this.sendEventArg = new SocketAsyncEventArgs();
            this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize);
            var sendDataToken = new DataToken()
            {
                Socket = exSocket
            };

            sendDataToken.bufferOffset     = this.sendEventArg.Offset;
            this.sendEventArg.UserToken    = sendDataToken;
            this.sendEventArg.AcceptSocket = acceptSocket;
            this.sendEventArg.Completed   += new EventHandler <SocketAsyncEventArgs>(IO_Completed);

            this.receiveEventArg = new SocketAsyncEventArgs();
            this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize);
            var receiveDataToken = new DataToken {
                Socket = exSocket, SyncSegments = new Queue <ArraySegment <byte> >()
            };

            receiveDataToken.bufferOffset     = this.receiveEventArg.Offset;
            this.receiveEventArg.UserToken    = receiveDataToken;
            this.receiveEventArg.AcceptSocket = acceptSocket;
            this.receiveEventArg.Completed   += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
            DataReceived += OnReceived;
            requestHandler.Bind(this);
        }
コード例 #10
0
        private void IO_Completed(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                DataToken ioDataToken = (DataToken)e.UserToken;
                ioDataToken.Socket.LastAccessTime = DateTime.Now;

                switch (e.LastOperation)
                {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;

                case SocketAsyncOperation.Send:
                    ProcessSend(e);
                    break;

                default:
                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
                }
            }
            catch (Exception ex)
            {
                TraceLog.WriteError("Socket Io error:{0}", ex);
            }
        }
コード例 #11
0
        private void IO_Completed(object sender, SocketAsyncEventArgs ioEventArgs)
        {
            try
            {
                DataToken ioDataToken = (DataToken)ioEventArgs.UserToken;

                switch (ioEventArgs.LastOperation)
                {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(ioEventArgs);
                    break;

                case SocketAsyncOperation.Send:
                    ProcessSend(ioEventArgs);
                    break;

                default:
                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
                }
            }
            catch (ObjectDisposedException)
            {
                ReleaseIOEventArgs(ioEventArgs);
            }
            catch (Exception ex)
            {
                logger.Error("IO_Completed", ex);
            }
        }
コード例 #12
0
        public override bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List <DataMeaage> messageList)
        {
            messageList = new List <DataMeaage>();
            int  remainingBytesToProcess = buffer.Length;
            bool needPostAnother         = true;

            do
            {
                if (dataToken.prefixBytesDone < 4)
                {
                    remainingBytesToProcess = HandlePrefix(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);
                    if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0))
                    {
                        byte[] bufferBytes = BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, dataToken.byteArrayForMessage);
                        string data        = Encoding.UTF8.GetString(bufferBytes);
                        //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉
                        TraceLog.WriteWarn("Receive Ip {1} message length error:{0}\r\nData:{2}", dataToken.messageLength, (dataToken != null ? dataToken.Socket.RemoteEndPoint.ToString() : ""), data);
                        needPostAnother = false;
                        break;
                    }
                    //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess);
                    if (remainingBytesToProcess == 0)
                    {
                        break;
                    }
                }

                remainingBytesToProcess = HandleMessage(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);

                if (dataToken.IsMessageReady)
                {
                    //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess);
                    messageList.Add(new DataMeaage()
                    {
                        Data = dataToken.byteArrayForMessage, OpCode = OpCode.Binary
                    });
                    if (remainingBytesToProcess != 0)
                    {
                        //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip);
                        dataToken.Reset(false);
                    }
                }
                else
                {
                    //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone);
                }
            } while (remainingBytesToProcess != 0);


            if (needPostAnother)
            {
                //继续处理下个请求包
                if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady)
                {
                    dataToken.Reset(true);
                }
                dataToken.bufferSkip = 0;
            }
            return(needPostAnother);
        }
コード例 #13
0
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            DataToken session = (DataToken)e.UserToken;

            if (e.SocketError == SocketError.Success)
            {
                session.messageBytesDone += e.BytesTransferred;

                if (session.messageBytesDone != session.messageLength)
                {
                    DoInternalSend(e);
                }
                else
                {
                    session.Reset(true);
                    // 触发数据发送成功事件
                    if (SendCompleted != null)
                    {
                        SendCompleted.BeginInvoke(e, null, null);
                    }
                }
            }
            else
            {
                session.Reset(true);
                ProcessSocketError(e);
            }
        }
コード例 #14
0
        private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs)
        {
            SocketAsyncResult result;

            if (socket.TryDequeue(out result))
            {
                DataToken dataToken = (DataToken)ioEventArgs.UserToken;
                dataToken.Socket              = socket;
                dataToken.AsyncResult         = result;
                dataToken.byteArrayForMessage = result.Data;
                dataToken.messageLength       = result.Data.Length;
                try
                {
                    PostSend(ioEventArgs);
                }
                catch (Exception ex)
                {
                    dataToken.ResultCallback(ResultCode.Error, ex);
                    ResetSendFlag();
                }
            }
            else
            {
                ResetSendFlag();
            }
        }
コード例 #15
0
        private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs)
        {
            bool isOwner = ioEventArgs == null;

            byte[] data;
            if (socket.TryDequeue(out data))
            {
                if (ioEventArgs == null)
                {
                    ioEventArgs = ioEventArgsPool.Pop();
                    ioEventArgs.AcceptSocket = socket.WorkSocket;
                }
                DataToken dataToken = (DataToken)ioEventArgs.UserToken;
                dataToken.Socket = socket;
                dataToken.byteArrayForMessage = data;
                dataToken.messageLength       = data.Length;
                try
                {
                    PostSend(ioEventArgs);
                }
                catch
                {
                    if (isOwner)
                    {
                        ReleaseIOEventArgs(ioEventArgs);
                    }
                    throw;
                }
            }
            else
            {
                ReleaseIOEventArgs(ioEventArgs);
                socket.ResetSendFlag();
            }
        }
コード例 #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        /// <param name="data"></param>
        public void Send(SocketAsyncEventArgs e, byte[] data)
        {
            DataToken session = e.UserToken as DataToken;

            session.byteArrayForMessage = data;
            session.messageLength       = data.Length;
            DoInternalSend(e);
        }
コード例 #17
0
ファイル: MessageHandler.cs プロジェクト: LeeWangyeol/Scut
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataToken"></param>
        /// <param name="buffer"></param>
        /// <param name="messageList"></param>
        /// <returns></returns>
        public override bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List<DataMeaage> messageList)
        {
            messageList = new List<DataMeaage>();
            int remainingBytesToProcess = buffer.Length;
            bool needPostAnother = true;
            do
            {
                if (dataToken.prefixBytesDone < 4)
                {
                    remainingBytesToProcess = HandlePrefix(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);
                    if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0))
                    {
                        byte[] bufferBytes = dataToken.byteArrayForMessage == null ?
                            BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, BufferUtils.GetBytes(buffer, dataToken.bufferSkip, buffer.Length - dataToken.bufferSkip)) :
                            BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, dataToken.byteArrayForMessage, buffer);
                        string data = Encoding.UTF8.GetString(bufferBytes);
                        //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉
                        TraceLog.Write("The host[{0}] request parser head byte error, byte len={1}\r\ndata:{2}",
                            dataToken.Socket.RemoteEndPoint.ToNotNullString(),
                            dataToken.messageLength,
                            data);
                        needPostAnother = false;
                        break;
                    }
                    //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess);
                    if (remainingBytesToProcess == 0) break;
                }

                remainingBytesToProcess = HandleMessage(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess);

                if (dataToken.IsMessageReady)
                {
                    //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess);
                    messageList.Add(new DataMeaage() { Data = dataToken.byteArrayForMessage, OpCode = OpCode.Binary });
                    if (remainingBytesToProcess != 0)
                    {
                        //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip);
                        dataToken.Reset(false);
                    }
                }
                else
                {
                    //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone);
                }
            } while (remainingBytesToProcess != 0);


            if (needPostAnother)
            {
                //继续处理下个请求包
                if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady)
                {
                    dataToken.Reset(true);
                }
                dataToken.bufferSkip = 0;
            }
            return needPostAnother;
        }
コード例 #18
0
ファイル: SocketListener.cs プロジェクト: dongliang/Scut
        /// <summary>
        ///
        /// </summary>
        /// <param name="socketObject"></param>
        /// <param name="data"></param>
        public void PushSend(SocketObject socketObject, byte[] data)
        {
            var e = _readWritePool.Pop();

            e.AcceptSocket = socketObject.Connection;
            DataToken token = (DataToken)e.UserToken;

            token.Socket = socketObject;
            _saeaProxy.Send(e, data);
        }
コード例 #19
0
        internal void StartReceive(SocketAsyncEventArgs receiveArgs)
        {
            DataToken session = receiveArgs.UserToken as DataToken;

            receiveArgs.SetBuffer(session.bufferOffset, BufferSize);

            if (!receiveArgs.AcceptSocket.ReceiveAsync(receiveArgs))
            {
                ProcessReceive(receiveArgs);
            }
        }
コード例 #20
0
ファイル: SocketListener.cs プロジェクト: dongliang/Scut
        private void ProcessAccept(SocketAsyncEventArgs acceptEventArg)
        {
            try
            {
                WaitHandle.WaitAll(_resetEvent);
                _resetEvent[0].Set();
                Socket clientSocket = acceptEventArg.AcceptSocket;
                if (clientSocket == null)
                {
                    acceptEventArg.AcceptSocket = null;
                    StartAccept(acceptEventArg);
                    return;
                }
                SocketAsyncEventArgs receiveEventArgs = _readWritePool.Pop();
                receiveEventArgs.AcceptSocket = acceptEventArg.AcceptSocket;
                DataToken    token        = (DataToken)receiveEventArgs.UserToken;
                SocketObject socketObject = new SocketObject(Guid.NewGuid(), acceptEventArg.AcceptSocket);
                socketObject.Init();
                socketObject.sessionPool    = _sessionPool;
                socketObject.LastAccessTime = DateTime.Now;
                token.Socket = socketObject;

#if DEBUG
                Console.WriteLine("{0}>>{1} connect success", DateTime.Now.ToLongTimeString(), token.RemoteAddress);
#endif
                _sessionPool.Put(socketObject);
                _saeaProxy.StartReceive(receiveEventArgs);
                _acceptPool.Push(acceptEventArg);

                if (ConnectCompleted != null)
                {
                    ConnectCompleted.BeginInvoke(new SocketProcessEventArgs()
                    {
                        Socket = socketObject
                    }, null, null);
                }
            }
            catch (SocketException ex)
            {
                DataToken token = acceptEventArg.UserToken as DataToken;
                TraceLog.WriteError("Listener Error when processing data received from {0}:\r\n{1}", acceptEventArg.RemoteEndPoint, ex);
            }
            catch (Exception ex)
            {
                TraceLog.WriteError("Listener error:{0}", ex.ToString());
            }

            // Accept the next connection request.
            acceptEventArg.AcceptSocket = null;
            StartAccept(acceptEventArg);
        }
コード例 #21
0
ファイル: ClientSocket.cs プロジェクト: suncle/Scut
 private void TryDequeueAndPostSend()
 {
     byte[] data;
     if (sendQueue.TryDequeue(out data))
     {
         DataToken dataToken = sendDataToken;
         dataToken.byteArrayForMessage = data;
         dataToken.messageLength       = data.Length;
         PostSend();
     }
     else
     {
         ResetSendFlag();
     }
 }
コード例 #22
0
ファイル: ClientSocket.cs プロジェクト: file1987/Scut
        private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs)
        {
            byte[] data;
            if (socket.TryDequeue(out data))
            {
                DataToken dataToken = (DataToken)ioEventArgs.UserToken;
                dataToken.Socket = socket;
                dataToken.byteArrayForMessage = data;
                dataToken.messageLength       = data.Length;

                PostSend(ioEventArgs);
            }
            else
            {
                ResetSendFlag();
            }
        }
コード例 #23
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        private void PostSend(SocketAsyncEventArgs ioEventArgs)
        {
            DataToken dataToken = (DataToken)ioEventArgs.UserToken;

            if (dataToken.messageLength - dataToken.messageBytesDone <= this.socketSettings.BufferSize)
            {
                ioEventArgs.SetBuffer(dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone);
                Buffer.BlockCopy(dataToken.byteArrayForMessage, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone);
            }
            else
            {
                ioEventArgs.SetBuffer(dataToken.bufferOffset, this.socketSettings.BufferSize);
                Buffer.BlockCopy(dataToken.byteArrayForMessage, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, this.socketSettings.BufferSize);
            }

            var willRaiseEvent = ioEventArgs.AcceptSocket.SendAsync(ioEventArgs);

            if (!willRaiseEvent)
            {
                ProcessSend(ioEventArgs);
            }
        }
コード例 #24
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        private void Init()
        {
            this.bufferManager.InitBuffer();

            for (int i = 0; i < this.socketSettings.MaxAcceptOps; i++)
            {
                this.acceptEventArgsPool.Push(CreateAcceptEventArgs());
            }

            SocketAsyncEventArgs ioEventArgs;

            for (int i = 0; i < this.socketSettings.NumOfSaeaForRecSend; i++)
            {
                ioEventArgs = new SocketAsyncEventArgs();
                this.bufferManager.SetBuffer(ioEventArgs);
                ioEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                DataToken dataToken = new DataToken();
                dataToken.bufferOffset = ioEventArgs.Offset;
                ioEventArgs.UserToken  = dataToken;
                this.ioEventArgsPool.Push(ioEventArgs);
            }
        }
コード例 #25
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs)
        {
            bool isOwner = ioEventArgs == null;
            SocketAsyncResult result;

            if (socket.TryDequeue(out result))
            {
                if (ioEventArgs == null)
                {
                    ioEventArgs = ioEventArgsPool.Pop();
                    ioEventArgs.AcceptSocket = socket.WorkSocket;
                }
                DataToken dataToken = (DataToken)ioEventArgs.UserToken;
                dataToken.Socket              = socket;
                dataToken.AsyncResult         = result;
                dataToken.byteArrayForMessage = result.Data;
                dataToken.messageLength       = result.Data.Length;
                try
                {
                    PostSend(ioEventArgs);
                }
                catch (Exception ex)
                {
                    dataToken.ResultCallback(ResultCode.Error, ex);
                    if (isOwner)
                    {
                        ReleaseIOEventArgs(ioEventArgs);
                    }
                    socket.ResetSendFlag();
                }
            }
            else
            {
                ReleaseIOEventArgs(ioEventArgs);
                socket.ResetSendFlag();
            }
        }
コード例 #26
0
        private int HandleMessage(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess)
        {
            if (dataToken.messageBytesDone == 0)
            {
                dataToken.byteArrayForMessage = new byte[dataToken.messageLength];
            }
            var nonCopiedBytes = 0;

            if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength)
            {
                var copyedBytes = dataToken.RemainByte;
                nonCopiedBytes = remainingBytesToProcess - copyedBytes;
                Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes);
                dataToken.messageBytesDone = dataToken.messageLength;
                dataToken.bufferSkip      += copyedBytes;
            }
            else
            {
                Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess);
                dataToken.messageBytesDone += remainingBytesToProcess;
            }

            return(nonCopiedBytes);
        }
コード例 #27
0
ファイル: MessageHandler.cs プロジェクト: juneman/Scut
        public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
        {
            if (dataToken.messageBytesDone == 0)
            {
                dataToken.byteArrayForMessage = new byte[dataToken.messageLength];
            }

            var nonCopiedBytes = 0;
            if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength)
            {
                var copyedBytes = dataToken.RemainByte;
                nonCopiedBytes = remainingBytesToProcess - copyedBytes;
                Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes);
                dataToken.messageBytesDone = dataToken.messageLength;
                dataToken.bufferSkip += copyedBytes;
            }
            else
            {
                Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess);
                dataToken.messageBytesDone += remainingBytesToProcess;
            }

            return nonCopiedBytes;
        }
コード例 #28
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="dataToken"></param>
 /// <param name="buffer"></param>
 /// <param name="messageList"></param>
 /// <returns></returns>
 public abstract bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List<DataMeaage> messageList);
コード例 #29
0
        /// <summary>
        /// 处理数据接收回调
        /// </summary>
        /// <param name="ioEventArgs"></param>
        private void ProcessReceive(SocketAsyncEventArgs ioEventArgs)
        {
            DataToken dataToken = (DataToken)ioEventArgs.UserToken;

            if (ioEventArgs.SocketError != SocketError.Success)
            {
                //Socket错误
                //if (logger.IsDebugEnabled) logger.Debug("ProcessReceive:{0}", ioEventArgs.SocketError);
                HandleCloseSocket(ioEventArgs);
                return;
            }

            if (ioEventArgs.BytesTransferred == 0)
            {
                //对方主动关闭socket
                //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket");
                HandleCloseSocket(ioEventArgs);
                return;
            }

            var exSocket = dataToken.Socket;

            #region 数据解析
            List <byte[]> msgs = new List <byte[]>();
            int           remainingBytesToProcess = ioEventArgs.BytesTransferred;
            bool          needPostAnother         = true;
            do
            {
                if (dataToken.prefixBytesDone < 4)
                {
                    remainingBytesToProcess = prefixHandler.HandlePrefix(ioEventArgs, dataToken, remainingBytesToProcess);
                    if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0))
                    {
                        //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉
                        logger.Warn("接收到的消息长度错误:{0}", dataToken.messageLength);
                        needPostAnother = false;
                        HandleCloseSocket(ioEventArgs);
                        break;
                    }
                    //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess);
                    if (remainingBytesToProcess == 0)
                    {
                        break;
                    }
                }

                remainingBytesToProcess = messageHandler.HandleMessage(ioEventArgs, dataToken, remainingBytesToProcess);

                if (dataToken.IsMessageReady)
                {
                    //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess);
                    msgs.Add(dataToken.byteArrayForMessage);
                    if (remainingBytesToProcess != 0)
                    {
                        //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip);
                        dataToken.Reset(false);
                    }
                }
                else
                {
                    //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone);
                }
            } while (remainingBytesToProcess != 0);
            #endregion

            if (needPostAnother)
            {
                if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady)
                {
                    dataToken.Reset(true);
                }
                dataToken.bufferSkip = 0;
                PostReceive(ioEventArgs);
            }

            foreach (var m in msgs)
            {
                try
                {
                    OnDataReceived(new ConnectionEventArgs {
                        Socket = exSocket, Data = m
                    });
                }
                catch (Exception ex)
                {
                    TraceLog.WriteError("OnDataReceived error:{0}", ex);
                }
            }
        }
コード例 #30
0
        private void ProcessReceive(SocketAsyncEventArgs ioEventArgs)
        {
            DataToken dataToken = (DataToken)ioEventArgs.UserToken;

            if (ioEventArgs.BytesTransferred == 0)
            {
                //对方主动关闭socket
                //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket");
                Closing(ioEventArgs, OpCode.Empty);
                return;
            }

            if (ioEventArgs.SocketError != SocketError.Success)
            {
                //Socket错误
                //if (logger.IsDebugEnabled) logger.Debug("Socket接收错误:{0}", ioEventArg.SocketError);
                Closing(ioEventArgs);
                return;
            }

            List <DataMeaage> messages;
            bool hasHandshaked;
            bool needPostAnother = requestHandler.TryReceiveMessage(ioEventArgs, out messages, out hasHandshaked);

            if (hasHandshaked)
            {
                DoOpened(new SocketEventArgs()
                {
                    Socket = dataToken.Socket
                });
            }
            // 触发收到消息事件
            if (messages != null)
            {
                foreach (var message in messages)
                {
                    try
                    {
                        if (message.OpCode == OpCode.Close)
                        {
                            var statusCode = requestHandler.MessageProcessor != null
                                      ? requestHandler.MessageProcessor.GetCloseStatus(message.Data)
                                      : OpCode.Empty;

                            if (statusCode != OpCode.Empty)
                            {
                                OnClosedStatus(statusCode);
                            }
                            Closing(ioEventArgs, OpCode.Empty);
                            needPostAnother = false;
                            break;
                        }
                        OnDataReceived(new SocketEventArgs {
                            Source = message, Socket = dataToken.Socket
                        });
                    }
                    catch (Exception ex)
                    {
                        logger.Error("OnDataReceived", ex);
                    }
                }
            }
            if (needPostAnother)
            {
                PostReceive(ioEventArgs);
            }
        }
コード例 #31
0
ファイル: ClientSocket.cs プロジェクト: haiya/Scut
        /// <summary>
        /// Connect this instance.
        /// </summary>
        public void Connect()
        {
            socket = new Socket(this.clientSettings.RemoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(this.clientSettings.RemoteEndPoint);
            connected = true;

            var buffer = new byte[this.clientSettings.BufferSize * 2];
            this.sendEventArg = new SocketAsyncEventArgs();
            this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize);
            this.sendDataToken = new DataToken();
            this.sendDataToken.bufferOffset = this.sendEventArg.Offset;
            this.sendEventArg.UserToken = this.sendDataToken;
            this.sendEventArg.AcceptSocket = socket;
            this.sendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);

            this.receiveEventArg = new SocketAsyncEventArgs();
            this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize);
            this.receiveDataToken = new DataToken();
            this.receiveDataToken.bufferOffset = this.receiveEventArg.Offset;
            this.receiveEventArg.UserToken = this.receiveDataToken;
            this.receiveEventArg.AcceptSocket = socket;
            this.receiveEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);

            PostReceive();
        }
コード例 #32
0
ファイル: SocketListener.cs プロジェクト: haiya/Scut
        private void Init()
        {
            this.bufferManager.InitBuffer();

            for (int i = 0; i < this.socketSettings.MaxAcceptOps; i++)
            {
                this.acceptEventArgsPool.Push(CreateAcceptEventArgs());
            }

            SocketAsyncEventArgs ioEventArgs;
            for (int i = 0; i < this.socketSettings.NumOfSaeaForRecSend; i++)
            {
                ioEventArgs = new SocketAsyncEventArgs();
                this.bufferManager.SetBuffer(ioEventArgs);
                ioEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
                DataToken dataToken = new DataToken();
                dataToken.bufferOffset = ioEventArgs.Offset;
                ioEventArgs.UserToken = dataToken;
                this.ioEventArgsPool.Push(ioEventArgs);
            }
        }
コード例 #33
0
ファイル: ClientSocket.cs プロジェクト: huangchenjun/Scut
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ioEventArgs"></param>
 /// <param name="opCode"></param>
 /// <param name="reason"></param>
 /// <param name="dataToken"></param>
 protected void Dispose(SocketAsyncEventArgs ioEventArgs, sbyte opCode, string reason, DataToken dataToken)
 {
     ReleaseIOEventArgs(ioEventArgs);
     Dispose(dataToken.Socket, opCode, reason);
 }
コード例 #34
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ioEventArgs"></param>
 /// <param name="opCode"></param>
 /// <param name="reason"></param>
 /// <param name="dataToken"></param>
 protected void Dispose(SocketAsyncEventArgs ioEventArgs, sbyte opCode, string reason, DataToken dataToken)
 {
     ReleaseIOEventArgs(ioEventArgs);
     Dispose(dataToken.Socket, opCode, reason);
 }
コード例 #35
0
ファイル: MessageHandler.cs プロジェクト: yunjoker/Scut
        private int HandlePrefix(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess)
        {
            if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone)
            {
                for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i];
                }
                remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone;
                dataToken.bufferSkip += 4 - dataToken.prefixBytesDone;
                dataToken.prefixBytesDone = 4;
                dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0);
            }
            else
            {
                for (int i = 0; i < remainingBytesToProcess; i++)
                {
                    dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i];
                }
                dataToken.prefixBytesDone += remainingBytesToProcess;
                remainingBytesToProcess = 0;
            }

            return remainingBytesToProcess;
        }
コード例 #36
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="saea"></param>
 /// <param name="dataToken"></param>
 /// <param name="remainingBytesToProcess"></param>
 /// <returns></returns>
 public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
 {
     return(HandleMessage(saea.Buffer, dataToken.DataOffset, dataToken, remainingBytesToProcess));
 }
コード例 #37
0
ファイル: ClientSocket.cs プロジェクト: huangchenjun/Scut
        private void Bind(Socket acceptSocket)
        {
            var exSocket = new ExSocket(acceptSocket);
            exSocket.LastAccessTime = DateTime.Now;
            var buffer = new byte[this.clientSettings.BufferSize * 2];
            this.sendEventArg = new SocketAsyncEventArgs();
            this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize);
            var sendDataToken = new DataToken() { Socket = exSocket };
            sendDataToken.bufferOffset = this.sendEventArg.Offset;
            this.sendEventArg.UserToken = sendDataToken;
            this.sendEventArg.AcceptSocket = acceptSocket;
            this.sendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);

            this.receiveEventArg = new SocketAsyncEventArgs();
            this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize);
            var receiveDataToken = new DataToken { Socket = exSocket, SyncSegments = new Queue<ArraySegment<byte>>() };
            receiveDataToken.bufferOffset = this.receiveEventArg.Offset;
            this.receiveEventArg.UserToken = receiveDataToken;
            this.receiveEventArg.AcceptSocket = acceptSocket;
            this.receiveEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
            DataReceived += OnReceived;
            requestHandler.Bind(this);
        }
コード例 #38
0
        /// <summary>
        /// 接收处理
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            DataToken session = e.UserToken as DataToken;

            if (e.BytesTransferred > 0)
            {
                if (e.SocketError == SocketError.Success)
                {
                    //是否有已接收但未处理的数据
                    int remainingBytesToProcess = e.BytesTransferred;
                    do
                    {
                        if (session.prefixBytesDone < 4)
                        {
                            remainingBytesToProcess = _prefixHandler.HandlePrefix(e, session, remainingBytesToProcess);
                            if (remainingBytesToProcess == 0)
                            {
                                session.bufferSkip = 0;
                                StartReceive(e);
                                return;
                            }
                        }

                        remainingBytesToProcess = _messageHandler.HandleMessage(e, session, remainingBytesToProcess);

                        if (session.IsMessageReady)
                        {
                            // 触发收到消息事件
                            if (ReceiveCompleted != null)
                            {
                                byte[] data = session.byteArrayForMessage;
                                ReceiveCompleted.BeginInvoke(new SocketProcessEventArgs()
                                {
                                    Socket = session.Socket, Data = data
                                }, null, null);
                            }
                            if (remainingBytesToProcess != 0)
                            {
                                session.Reset(false);
                            }
                        }
                    }while (remainingBytesToProcess != 0);

                    if (session.prefixBytesDone == 4 && session.IsMessageReady)
                    {
                        session.Reset(true);
                    }
                    session.bufferSkip = 0;
                    StartReceive(e);
                }
                else
                {
                    session.Reset(true);
                    ProcessSocketError(e);
                }
            }
            else
            {
                session.Reset(true);
                CloseClientSocket(e);
            }
        }
コード例 #39
0
ファイル: SocketListener.cs プロジェクト: zhangxiangbing/Scut
        /// <summary>
        /// 处理数据接收回调
        /// </summary>
        /// <param name="ioEventArgs"></param>
        private void ProcessReceive(SocketAsyncEventArgs ioEventArgs)
        {
            DataToken dataToken = (DataToken)ioEventArgs.UserToken;

            if (ioEventArgs.BytesTransferred == 0)
            {
                //对方主动关闭socket
                //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket");
                Closing(ioEventArgs, OpCode.Empty);
                return;
            }

            if (ioEventArgs.SocketError != SocketError.Success)
            {
                //Socket错误
                logger.Debug("IP {0} ProcessReceive:{1}", (dataToken != null ? dataToken.Socket.RemoteEndPoint.ToNotNullString() : ""), ioEventArgs.SocketError);
                Closing(ioEventArgs);
                return;
            }
            ExSocket          exSocket = dataToken == null ? null : dataToken.Socket;
            List <DataMeaage> messages;
            bool hasHandshaked;
            bool needPostAnother = requestHandler.TryReceiveMessage(ioEventArgs, out messages, out hasHandshaked);

            if (hasHandshaked)
            {
                OnHandshaked(new ConnectionEventArgs {
                    Socket = exSocket
                });
            }

            //modify reason:数据包接收事件触发乱序
            if (messages != null)
            {
                foreach (var message in messages)
                {
                    try
                    {
                        switch (message.OpCode)
                        {
                        case OpCode.Close:
                            var statusCode = requestHandler.MessageProcessor != null
                                    ? requestHandler.MessageProcessor.GetCloseStatus(message.Data)
                                    : OpCode.Empty;

                            if (statusCode != OpCode.Empty)
                            {
                                DoClosedStatus(exSocket, statusCode);
                            }
                            Closing(ioEventArgs, OpCode.Empty);
                            needPostAnother = false;
                            break;

                        case OpCode.Ping:
                            DoPing(new ConnectionEventArgs {
                                Socket = exSocket, Meaage = message
                            });
                            break;

                        case OpCode.Pong:
                            DoPong(new ConnectionEventArgs {
                                Socket = exSocket, Meaage = message
                            });
                            break;

                        default:
                            OnDataReceived(new ConnectionEventArgs {
                                Socket = exSocket, Meaage = message
                            });
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceLog.WriteError("OnDataReceived error:{0}", ex);
                    }
                }
            }
            if (needPostAnother)
            {
                PostReceive(ioEventArgs);
                //是否需要关闭连接
                if (exSocket.IsClosed)
                {
                    ResetSAEAObject(ioEventArgs);
                }
            }
        }
コード例 #40
0
ファイル: MessageHandler.cs プロジェクト: yunjoker/Scut
 /// <summary>
 /// 
 /// </summary>
 /// <param name="saea"></param>
 /// <param name="dataToken"></param>
 /// <param name="remainingBytesToProcess"></param>
 /// <returns></returns>
 public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess)
 {
     return HandleMessage(saea.Buffer, dataToken.DataOffset, dataToken, remainingBytesToProcess);
 }
コード例 #41
0
ファイル: MessageHandler.cs プロジェクト: yunjoker/Scut
        private int HandleMessage(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess)
        {
            if (dataToken.messageBytesDone == 0)
            {
                dataToken.byteArrayForMessage = new byte[dataToken.messageLength];
            }
            var nonCopiedBytes = 0;
            if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength)
            {
                var copyedBytes = dataToken.RemainByte;
                nonCopiedBytes = remainingBytesToProcess - copyedBytes;
                Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes);
                dataToken.messageBytesDone = dataToken.messageLength;
                dataToken.bufferSkip += copyedBytes;
            }
            else
            {
                Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess);
                dataToken.messageBytesDone += remainingBytesToProcess;
            }

            return nonCopiedBytes;
        }