patterncsharpMinor
SocketAsyncEventArgs send and receive
Viewed 0 times
andreceivesocketasynceventargssend
Problem
I been working on getting the
```
///
/// The settings to use with this ServerSocket.
///
ServerSocketSettings Settings;
///
/// The buffer manager for allocation a buffer block to a SocketAsyncEventArgs.
///
BufferManager BufferManager;
///
/// The semaphore used for controlling the max connections to the server.
///
SemaphoreSlim MaxConnectionsEnforcer;
///
/// The socket used for listening for incoming connections.
///
Socket ListenSocket;
///
/// The pool of re-usable SocketAsyncEventArgs for accept operations.
///
SocketAsyncEventArgsPool PoolOfAcceptEventArgs;
///
/// The pool of re-usable SocketAsyncEventArgs for receiving data.
///
SocketAsyncEventArgsPool PoolOfRecEventArgs;
///
/// The pool of re-usable SocketAsyncEventArgs for sending data.
///
SocketAsyncEventArgsPool PoolOfSendEventArgs;
///
/// Initializes a new instance of the Non-blocking I/O ServerSocket.
///
/// The settings to use with this ServerSocket.
public ServerSocket(ServerSocketSettings settings)
{
this.Settings = settings;
this.BufferManager = new BufferManager((this.Settings.BufferSize this.Settings.NumOfSaeaForRec) + (this.Settings.BufferSize this.Settings.NumOfSaeaForSend) * this.Settings.OpsToPreAllocate,
this.Settings.BufferSize * this.Settings.OpsToPreAllocate);
this.PoolOfAcceptEventArgs = new SocketAsyncEventArgsPool(this.Settings.MaxSimultaneousAcceptOps);
this.PoolOfRecEventArgs = new SocketAsyncEventArgsPool(this.Settings.NumOfSaeaForRec);
this.PoolOfSendEventArgs = new SocketAsyncEventArgsPool(this.Settings.NumOfSaeaForSend);
this.MaxConnectionsEnforcer = new SemaphoreSlim(this.Settings.MaxConnections, this.Settings.MaxConnections);
}
internal void Init()
{
this.BufferManager.InitBuffer();
for (int i = 0; i (AcceptEventArg_Completed);
this.PoolOfAcceptEventArgs.Push(acceptEventA
SocketAsyncEventArgs to work the way I want it to work. Now I was wondering: is this going to work how it should work?```
///
/// The settings to use with this ServerSocket.
///
ServerSocketSettings Settings;
///
/// The buffer manager for allocation a buffer block to a SocketAsyncEventArgs.
///
BufferManager BufferManager;
///
/// The semaphore used for controlling the max connections to the server.
///
SemaphoreSlim MaxConnectionsEnforcer;
///
/// The socket used for listening for incoming connections.
///
Socket ListenSocket;
///
/// The pool of re-usable SocketAsyncEventArgs for accept operations.
///
SocketAsyncEventArgsPool PoolOfAcceptEventArgs;
///
/// The pool of re-usable SocketAsyncEventArgs for receiving data.
///
SocketAsyncEventArgsPool PoolOfRecEventArgs;
///
/// The pool of re-usable SocketAsyncEventArgs for sending data.
///
SocketAsyncEventArgsPool PoolOfSendEventArgs;
///
/// Initializes a new instance of the Non-blocking I/O ServerSocket.
///
/// The settings to use with this ServerSocket.
public ServerSocket(ServerSocketSettings settings)
{
this.Settings = settings;
this.BufferManager = new BufferManager((this.Settings.BufferSize this.Settings.NumOfSaeaForRec) + (this.Settings.BufferSize this.Settings.NumOfSaeaForSend) * this.Settings.OpsToPreAllocate,
this.Settings.BufferSize * this.Settings.OpsToPreAllocate);
this.PoolOfAcceptEventArgs = new SocketAsyncEventArgsPool(this.Settings.MaxSimultaneousAcceptOps);
this.PoolOfRecEventArgs = new SocketAsyncEventArgsPool(this.Settings.NumOfSaeaForRec);
this.PoolOfSendEventArgs = new SocketAsyncEventArgsPool(this.Settings.NumOfSaeaForSend);
this.MaxConnectionsEnforcer = new SemaphoreSlim(this.Settings.MaxConnections, this.Settings.MaxConnections);
}
internal void Init()
{
this.BufferManager.InitBuffer();
for (int i = 0; i (AcceptEventArg_Completed);
this.PoolOfAcceptEventArgs.Push(acceptEventA
Solution
Just a couple observations, unfortunately not directly related to your primary concerns but still [hopefully] valuable input from a code review perspective:
You could create a class that cleanly exposes what you need, and only cast
And now you can consistently cast
- The class is tightly coupled with several other classes. This may or may not be problematic, just thought I'd point it out - I consider instantiating objects as a concern on its own, I don't like having
newinstructions all over my code, so I'd try to move these instructions outside the class if possible.
Init()has too many responsibilities, I would extract 3 methods from that code (one for each loop).
SocketAsyncEventArgs.UserTokenis anobject, for convenience. It seems you're sometimes putting aConnectionin there, and other times aSendDataToken. This is likely to get confusing and result inInvalidCastExceptionoccurrences as the code gets maintained and evolves.
You could create a class that cleanly exposes what you need, and only cast
UserToken to that type:public class CustomUserToken
{
public class CustomUserToken(Connection connection, SendDataToken token)
{
_connection = connection;
_token = token;
}
private readonly Connection _connection;
public Connection Connection { get { return _connection; } }
private readonly SendDataToken _token;
public SendDataToken Token { get { return _token; } }
}And now you can consistently cast
SockedAsyncEventArgs.UserToken to CustomUserToken, and get the Connection and Token from there.Code Snippets
public class CustomUserToken
{
public class CustomUserToken(Connection connection, SendDataToken token)
{
_connection = connection;
_token = token;
}
private readonly Connection _connection;
public Connection Connection { get { return _connection; } }
private readonly SendDataToken _token;
public SendDataToken Token { get { return _token; } }
}Context
StackExchange Code Review Q#8361, answer score: 5
Revisions (0)
No revisions yet.