简体   繁体   中英

SocketAsyncEventArgs in a duplex server environment?

I am learning to use the SocketAsyncEventArgs stuff using the MSDN tutorial. I was just wondering a few things, namely how I could go about implementing the server with full-duplex capabilities.

Currently, the MSDN example teaches you to create a server that first listens, then when something is received, to send it back. Only then does the server start listening again.

The problem I am having coming up with my own solution is that the SocketAsyncEventArgs object has only one event, Completed that is fired for both sends and receives. It has no other events.

I read on some horribly translated site that I

must use two SocketAsyncEventArgs, one receives a hair.

- unknown

I find there is a disturbingly small amount of infromation on this supposedly "enhanced" socket implementation...

Heres a little bit of my code so you can see what i'm up to.

        //Called when a SocketAsyncEventArgs raises the completed event
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            Token Token = (Token)e.UserToken;

            if(e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                Interlocked.Add(ref TotalBytesRead, e.BytesTransferred);
                Console.WriteLine(String.Format("Received from {0}", ((Token)e.UserToken).Socket.RemoteEndPoint.ToString()));

                bool willRaiseEvent = ((Token)e.UserToken).Socket.ReceiveAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessReceive(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }

        private void ProcessSend(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                // done echoing data back to the client
                Token token = (Token)e.UserToken;
                // read the next block of data send from the client
                bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessReceive(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }

        void IOCompleted(object sender, SocketAsyncEventArgs e)
        {
            // determine which type of operation just completed and call the associated handler
            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");
            }

        }

Thanks!

The solution was to create a separate SocketAsyncEventArgs for both Send and Receive .

It takes a bit more memory but not much because there is no need to allocate a buffer to the Send args.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM