Пример #1
0
        /// <summary>
        /// This method is called by I/O Completed() when an asynchronous send completes.
        /// If all of the data has been sent, then this method calls StartReceive
        /// to start another receive op on the socket to read any additional
        /// data sent from the client. If all of the data has NOT been sent, then it
        /// calls StartSend to send more data.
        /// </summary>
        /// <param name="e"></param>
        private void ProcessSend(SocketAsyncEventArgs receiveSendEventArgs)
        {
            DataHoldingUserToken receiveSendToken =
                (DataHoldingUserToken)receiveSendEventArgs.UserToken;

            receiveSendToken.sendBytesRemainingCount =
                receiveSendToken.sendBytesRemainingCount
                - receiveSendEventArgs.BytesTransferred;
            receiveSendToken.bytesSentAlreadyCount +=
                receiveSendEventArgs.BytesTransferred;

            if (receiveSendEventArgs.SocketError == SocketError.Success)
            {
                if (receiveSendToken.sendBytesRemainingCount == 0)
                {
                    StartReceive(receiveSendEventArgs);
                }
                else
                {
                    //If some of the bytes in the message have NOT been sent,
                    //then we will need to post another send operation.
                    //So let's loop back to StartSend().
                    StartSend(receiveSendEventArgs);
                }
            }
            else
            {
                //If we are in this else-statement, there was a socket error.
                //In this example we'll just close the socket if there was a socket error
                //when receiving data from the client.
                receiveSendToken.Reset();
                CloseClientSocket(receiveSendEventArgs);
            }
        }
Пример #2
0
        /// <summary>
        /// This method is invoked by the IO_Completed method
        /// when an asynchronous receive operation completes.
        /// If the remote host closed the connection, then the socket is closed.
        /// Otherwise, we process the received data. And if a complete message was
        /// received, then we do some additional processing, to
        /// respond to the client.
        /// </summary>
        /// <param name="receiveSendEventArgs"></param>
        private void ProcessReceive(SocketAsyncEventArgs receiveSendEventArgs)
        {
            DataHoldingUserToken receiveSendToken =
                (DataHoldingUserToken)receiveSendEventArgs.UserToken;

            // If there was a socket error, close the connection. This is NOT a normal
            // situation, if you get an error here.
            // In the Microsoft example code they had this error situation handled
            // at the end of ProcessReceive. Putting it here improves readability
            // by reducing nesting some.
            if (receiveSendEventArgs.SocketError != SocketError.Success)
            {
                receiveSendToken.Reset();
                CloseClientSocket(receiveSendEventArgs);

                // Jump out of the ProcessReceive method.
                return;
            }

            // If no data was received, close the connection. This is a NORMAL
            // situation that shows when the client has finished sending data.
            if (receiveSendEventArgs.BytesTransferred == 0)
            {
                receiveSendToken.Reset();
                CloseClientSocket(receiveSendEventArgs);
                return;
            }

            // The BytesTransferred property tells us how many bytes
            // we need to process.
            Int32 remainingBytesToProcess = receiveSendEventArgs.BytesTransferred;

            // If we have not got all of the prefix already,
            // then we need to work on it here.
            if (receiveSendToken.receivedPrefixBytesDoneCount < this.socketListenerSettings.ReceivePrefixLength)
            {
                remainingBytesToProcess = prefixHandler.HandlePrefix(receiveSendEventArgs,
                                                                     receiveSendToken, remainingBytesToProcess);

                if (remainingBytesToProcess == 0)
                {
                    // We need to do another receive op, since we do not have
                    // the message yet, but remainingBytesToProcess == 0.
                    StartReceive(receiveSendEventArgs);
                    // Jump out of the method.
                    return;
                }
            }

            // If we have processed the prefix, we can work on the message now.
            // We'll arrive here when we have received enough bytes to read
            // the first byte after the prefix.
            bool incomingTcpMessageIsReady = messageHandler.HandleMessage(receiveSendEventArgs,
                                                                          receiveSendToken, remainingBytesToProcess);

            if (incomingTcpMessageIsReady == true)
            {
                // Pass the DataHolder object to the Mediator here. The data in
                // this DataHolder can be used for all kinds of things that an
                // intelligent and creative person like you might think of.
                receiveSendToken.theMediator.HandleData(receiveSendToken.theDataHolder);

                // Create a new DataHolder for next message.
                receiveSendToken.CreateNewDataHolder();

                //Reset the variables in the UserToken, to be ready for the
                //next message that will be received on the socket in this
                //SAEA object.
                receiveSendToken.Reset();

                receiveSendToken.theMediator.PrepareOutgoingData();
                StartSend(receiveSendToken.theMediator.GiveBack());
            }
            else
            {
                // Since we have NOT gotten enough bytes for the whole message,
                // we need to do another receive op. Reset some variables first.

                // All of the data that we receive in the next receive op will be
                // message. None of it will be prefix. So, we need to move the
                // receiveSendToken.receiveMessageOffset to the beginning of the
                // receive buffer space for this SAEA.
                receiveSendToken.receiveMessageOffset = receiveSendToken.bufferOffsetReceive;

                // Do NOT reset receiveSendToken.receivedPrefixBytesDoneCount here.
                // Just reset recPrefixBytesDoneThisOp.
                receiveSendToken.recPrefixBytesDoneThisOp = 0;

                // Since we have not gotten enough bytes for the whole message,
                // we need to do another receive op.
                StartReceive(receiveSendEventArgs);
            }
        }