Example #1
0
        private void SendAsync(AsyncUserToken token, byte[] dataInBytes)
        {
            byte[] buffer     = new byte[dataInBytes.Length + DATA_CHUNK_HEADER_LENGTH];
            byte[] bodyLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(dataInBytes.Length)); /*将body的长度转成字节数组*/

            Array.Copy(bodyLength, buffer, 4);                                                           //bodyLength
            Array.Copy(dataInBytes, 0, buffer, 4, dataInBytes.Length);                                   //将数据放置进去.
            Array.Copy(buffer, 0, token.SendSocketAsyncEventArgs.Buffer, token.SendSocketAsyncEventArgs.Offset, buffer.Length);

            token.IsSendSocketAsyncEventArgsCanBeUsedEvent.WaitOne();
            token.SendSocketAsyncEventArgs.SetBuffer(token.SendSocketAsyncEventArgs.Offset, dataInBytes.Length + DATA_CHUNK_HEADER_LENGTH);
            if (!token.Socket.SendAsync(token.SendSocketAsyncEventArgs))
            {
                ProcessSend(token.SendSocketAsyncEventArgs);
            }
        }
Example #2
0
        public void Init()
        {
            _bufferManager.Init();

            for (int i = 0; i < _listenBacklog; i++)
            {
                AsyncUserToken userToken = new AsyncUserToken();
                userToken.ReceiveSocketAsyncEventArgs.Completed += IO_Completed;
                userToken.ReceiveSocketAsyncEventArgs.UserToken  = userToken;

                userToken.SendSocketAsyncEventArgs.Completed += IO_Completed;
                userToken.SendSocketAsyncEventArgs.UserToken  = userToken;

                _bufferManager.SetBuffer(userToken.ReceiveSocketAsyncEventArgs);
                _bufferManager.SetBuffer(userToken.SendSocketAsyncEventArgs);

                _userTokenPool.Push(userToken);
            }
        }
Example #3
0
        /*对数据进行打包,然后再发送, dataInBytes是一个完整的数据包*/
        public void SendData(AsyncUserToken token, byte[] dataInBytes)
        {
            if (token == null)
            {
                _log.Info("AsyncServer->SendData: 发送未完成, token为空");
                return;
            }
            else if (token.Socket == null)
            {
                _log.Info("AsyncServer->SendData: 发送未完成, token.Socket为空");
                return;
            }
            else if (!token.Socket.Connected)
            {
                string clientIP = string.Empty;
                if (token.Socket != null)
                {
                    clientIP = token.Socket.RemoteEndPoint.ToString();
                }
                _log.Info(string.Format("AsyncServer->SendData: 发送未完成, token.Socket.Connected未连接到远程客户端, clientIP = {0}", clientIP));
                return;
            }

            try
            {
                /*对要发送的消息,制定简单协议,头4字节指定包的大小,方便客户端接收(协议可以自己定)*/
                //SendAsync(token, dataInBytes);
                //SendSync(token, dataInBytes);

                /*发的包长度过大,则分包发送*/
                byte[] buffer     = new byte[dataInBytes.Length + DATA_CHUNK_HEADER_LENGTH];
                byte[] bodyLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(dataInBytes.Length)); /*将body的长度转成字节数组*/

                Array.Copy(bodyLength, buffer, 4);                                                           //bodyLength
                Array.Copy(dataInBytes, 0, buffer, 4, dataInBytes.Length);                                   //将数据放置进去.

                if (buffer.Length <= BUFFER_SIZE)
                {
                    token.Socket.Send(buffer);
                }
                else
                {
                    byte[] byteArrayTemp = buffer;
                    while (true)
                    {
                        byte[] dataToSend = byteArrayTemp.Take(BUFFER_SIZE).ToArray();
                        if (dataToSend.Length > 0)
                        {
                            token.Socket.Send(dataToSend);
                        }
                        else
                        {
                            break;
                        }
                        byteArrayTemp = byteArrayTemp.Skip(BUFFER_SIZE).ToArray();
                    }
                }
            }
            catch (Exception ex)
            {
                _log.ErrorFormat("AsyncServer->SendData出现异常, Exception = {0}", ex);
            }
        }
Example #4
0
 /*抽象数据处理方法,receivedBytes是一个完整的包*/
 protected virtual void ProcessData(AsyncUserToken asyncUserToken, byte[] receivedBytes)
 {
 }
Example #5
0
        private void ProcessReceive(SocketAsyncEventArgs readEventArgs)
        {
            /*需要检查客户端是否关闭了连接*/
            AsyncUserToken asyncUserToken = readEventArgs.UserToken as AsyncUserToken;

            if (readEventArgs.BytesTransferred > 0 && readEventArgs.SocketError == SocketError.Success)
            {
                Interlocked.Add(ref _totalBytesReceived, (long)readEventArgs.BytesTransferred);
                _log.Info(string.Format("目前服务器已接受{0}字节的数据", _totalBytesReceived));

                /*读取缓冲区中的数据*/
                /*半包, 粘包*/
                try
                {
                    /*读取数据*/
                    byte[] dataTransfered = new byte[readEventArgs.BytesTransferred];
                    Array.Copy(readEventArgs.Buffer, readEventArgs.Offset, dataTransfered, 0, readEventArgs.BytesTransferred);
                    asyncUserToken.Buffer.AddRange(dataTransfered);

                    /* 4字节包头(长度) + 包体*/
                    /* Header + Body */

                    /* 接收到的数据可能小于一个包的大小,需分多次接收
                     * 先判断包头的大小,够一个完整的包再处理
                     */

                    while (asyncUserToken.Buffer.Count > DATA_CHUNK_HEADER_LENGTH)
                    {
                        /*判断包的长度*/
                        byte[] lenBytes = asyncUserToken.Buffer.GetRange(0, DATA_CHUNK_HEADER_LENGTH).ToArray();
                        int    bodyLen  = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(lenBytes, 0));        //包体的长度

                        var packageLength = DATA_CHUNK_HEADER_LENGTH + bodyLen;                                   //一个数据包的长度,4字节包头 + 包体的长度
                        var receivedLengthExcludeHeader = asyncUserToken.Buffer.Count - DATA_CHUNK_HEADER_LENGTH; //去掉包头之后接收的长度

                        /*接收的数据长度不够时,退出循环,让程序继续接收*/
                        if (receivedLengthExcludeHeader < bodyLen)
                        {
                            break;
                        }

                        /*接收的数据长度大于一个包的长度时,则提取出来,交给后面的程序去处理*/
                        byte[] receivedBytes = asyncUserToken.Buffer.GetRange(DATA_CHUNK_HEADER_LENGTH, bodyLen).ToArray();
                        asyncUserToken.Buffer.RemoveRange(0, packageLength); /*从缓冲区重移出取出的数据*/

                        /*抽象数据处理方法,receivedBytes是一个完整的包*/
                        ProcessData(asyncUserToken, receivedBytes);
                    }

                    /*继续接收, 非常关键的一步*/
                    if (asyncUserToken.Socket != null)
                    {
                        if (asyncUserToken.Socket.Connected)
                        {
                            if (!asyncUserToken.Socket.ReceiveAsync(readEventArgs))
                            {
                                this.ProcessReceive(readEventArgs);
                            }
                        }
                        else
                        {
                            string clientIP = string.Empty;
                            if (asyncUserToken.Socket != null)
                            {
                                clientIP = asyncUserToken.Socket.RemoteEndPoint.ToString();
                            }

                            _log.Debug(string.Format("AsyncServerBase->ProcessReceive: 已断开与远程客户端的连接, clientIP = {0}", clientIP));
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("AsyncServer->ProcessReceive出现异常, Exception = {0}", ex);
                }
            }
            else
            {
                CloseClientSocket(asyncUserToken);
            }
        }
Example #6
0
 public void Push(AsyncUserToken token)
 {
     _stack.Push(token);
 }