问题
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