예제 #1
0
        void ProcessReceived(SocketAsyncEventArgs e)
        {
            //..
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                AsyncUserToken token = (AsyncUserToken)e.UserToken;

                int offset        = 0;                           // token.BytesReceivedStatic;
                int bytesExpected = 0;                           // token.BytesExpected;

                token.BytesReceivedDynamic = e.BytesTransferred; // bytes received this time
                token.BytesReceivedStatic += e.BytesTransferred; // bytes accumulated in the buffer

                if (ReportReceivedProgress != null)
                {
                    ReportReceivedProgress(e, token);
                }

                bool hasCompletedMessage = true;
                while (hasCompletedMessage)
                {
                    if (token.IsHead) // is head, read the prefix length
                    {
                        // incomplete prefix bytes
                        if (token.BytesReceivedStatic < 4)
                        {
                            break;
                        }

                        token.BytesExpected = BitConverter.ToInt32(e.Buffer, 0);

                        if (token.BytesExpected == 0)
                        {
                            // heartbeat message
                            // remove 4 bytes at head
                            Buffer.BlockCopy(e.Buffer, 4, e.Buffer, 0, token.BytesReceivedStatic - 4);

                            // continue to receive
                            break;
                        }

                        // expand the buffer size when the buffer is not large enough
                        if (token.BytesExpected > receiveBuffer.Length)
                        {
                            byte[] temp = new byte[token.BytesExpected * 2];
                            Buffer.BlockCopy(e.Buffer, 0, temp, 0, e.Buffer.Length);
                            receiveBuffer = temp;
                            e.SetBuffer(temp, 0, temp.Length);
                        }

                        token.IsHead = false;
                    }

                    // if bytes accumulated in the buffer is greater than or equals to bytes expected
                    hasCompletedMessage = token.BytesReceivedStatic >= token.BytesExpected;
                    //
                    if (hasCompletedMessage) // at least one complete message
                    {
                        // deliver the first message in the buffer
                        byte[] receivedData = new byte[token.BytesExpected - 4];
                        Buffer.BlockCopy(receiveBuffer, 4, receivedData, 0, receivedData.Length);
                        OnDataReceivedCompleted(this, receivedData);

                        token.IsHead = true; // reset the head flag

                        // valid bytes left in the buffer
                        int bytesLeftInBuffer = token.BytesReceivedStatic - token.BytesExpected;

                        // shift the incomplete data to the head of the buffer
                        // TODO:
                        // FIXME: only do shift the last incomplete data
                        Buffer.BlockCopy(e.Buffer, token.BytesExpected, e.Buffer, 0, bytesLeftInBuffer);

                        // reset the bytes of valid data in the buffer
                        token.BytesReceivedStatic = bytesLeftInBuffer;
                    }
                }

                // append the following data to the buffer from offset position
                offset = token.BytesReceivedStatic; // start position of the buffer

                bytesExpected =
                    //// only expected message length bytes
                    //token.BytesExpected - token.BytesReceivedStatic;
                    //// expected bytes as much as the buffer can hold
                    e.Buffer.Length - token.BytesReceivedStatic;

                e.SetBuffer(offset, bytesExpected);
                e.UserToken = token;

                if (!clientSocket.ReceiveAsync(e))
                {
                    ProcessReceived(e);
                }
            }
            else
            {
                CloseConnection();
            }
        }
예제 #2
0
 void a_conn_ReportSendProgress(SocketAsyncEventArgs e, AsyncUserToken token)
 {
     if (this.ReportSendProgress != null)
         this.ReportSendProgress(e, token);
 }