SocketAsyncEventArgs in a duplex server environment?

冷暖自知 提交于 2020-06-29 11:52:09

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/41645602/socketasynceventargs-in-a-duplex-server-environment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!