Ejemplo n.º 1
0
        /// <summary>
        /// This method is called when we need to create a new SAEA object to do
        /// accept operations. The reason to put it in a separate method is so that
        /// we can easily add more objects to the pool if we need to.
        /// You can do that if you do NOT use a buffer in the SAEA object that does
        /// the accept operations.
        /// </summary>
        /// <param name="pool"></param>
        /// <returns></returns>
        internal SocketAsyncEventArgs CreateNewSaeaForAccept(SocketAsyncEventArgsPool pool)
        {
            // Allocate the SocketAsyncEventArgs object.
            SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs();

            // SocketAsyncEventArgs.Completed is an event(the only event),
            // declared in the SocketAsyncEventArgs class.
            // See http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.completed.aspx
            // An event handler should be attached to the event within
            // a SocketAsyncEventArgs instance when an asynchronous socket
            // operation is initiated, otherwise the application will not be able
            // to determine when the operation completes.
            // Attach the event handler, which causes the calling of the
            // AcceptEventArg_Completed object when the accept op completes.
            acceptEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(AcceptEventArg_Completed);

            AcceptOpUserToken theAcceptOpToken = new
                                                 AcceptOpUserToken(pool.AssignTokenId() + 10000);

            acceptEventArg.UserToken = theAcceptOpToken;

            return(acceptEventArg);

            // accept operations do NOT need a buffer.
            //You can see that is true by looking at the
            //methods in the .NET Socket class on the Microsoft website. AcceptAsync does
            //not require a parameter for buffer size.
        }
Ejemplo n.º 2
0
        /// <summary>
        /// The e parameter passed from the AcceptEventArg_Completed method
        /// respents the SocketAsyncEventArgs object that did
        /// the accept operation. In this method we'll do the handoff from it to the
        /// SocketAsyncEventArgs object that will do receive/send.
        /// </summary>
        /// <param name="e"></param>
        private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
        {
            // This is when there was an error with the accept op. That should NOT
            // be happening often. It could indicate that there is a problem with
            // that socket. If there is a problem, then we would have an infinite
            // loop here, if we tried to reuse that same socket.
            if (acceptEventArgs.SocketError != SocketError.Success)
            {
                // Loop back to post another accept op. Notice that we are NOT
                // passing the SAEA object here.
                LoopToStartAccept();

                AcceptOpUserToken theAcceptOpToken = (AcceptOpUserToken)acceptEventArgs.UserToken;

                // Let's destroy this socket, since it could be bad.
                HandleBadAccept(acceptEventArgs);

                // Jump out of the method
                return;
            }

            // Now that the accept operation completed, we can start another
            // accept operation, which will do the same. Notice that we are NOT
            // passing the SAEA object here.
            LoopToStartAccept();

            // Get a SocketAsyncEventArgs object from the pool of received/send op
            // SocketAsyncEventArgs objects
            SocketAsyncEventArgs receiveSendEventArgs = this.poolOfRecSendEventArgs.Pop();

            // Create sessionId in UserToken.
            ((DataHoldingUserToken)receiveSendEventArgs.UserToken).CreateSessionId();

            // A new socket was created by the AcceptAsync method. The
            // SocketAsyncEventArgs object which did the accept operation has that
            // socket info in its AcceptSocket property. Now we will give
            // a reference for that socket to the SocketAsyncEventArgs
            // object which will do receive/send.
            receiveSendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket;

            // We have handed off the connection info from the
            // accepting socket to the receiving socket. So, now we can
            // put the SocketAsyncEventArgs object that did the accept operation
            // back in the pool for them. But first we will clear
            // the socket info from that object, so it will be
            // ready for a new socket when it comes out of the pool.
            acceptEventArgs.AcceptSocket = null;
            this.poolOfRecSendEventArgs.Push(acceptEventArgs);

            StartReceive(receiveSendEventArgs);
        }