SocketAsyncResult Class
The SocketAsyncResult class is an internal class used by the .NET Framework to manage the state of asynchronous socket operations. It encapsulates the details of the operation, including the data buffer, the offset and count of bytes to transfer, and the completion callback delegate. Developers typically do not interact with this class directly, but rather through the asynchronous methods provided by the Socket class.
Inheritance
System.Object > System.Net.Sockets.SocketAsyncResult
Constructors
This class has no public constructors.
Properties
| Name | Description |
|---|---|
AsyncState |
Gets or sets user-defined state information. |
BytesTransferred |
Gets the number of bytes transferred by the asynchronous operation. |
CompletedSynchronously |
Gets a value indicating whether the asynchronous operation completed synchronously. |
Error |
Gets the exception that occurred during the asynchronous operation. |
IsCompleted |
Gets a value indicating whether the asynchronous operation has completed. |
IsOneWay |
Gets a value indicating whether the operation is a one-way operation (no response expected). |
SocketFlags |
Gets the socket flags used in the operation. |
Methods
This class has no public methods.
Remarks
When you call an asynchronous socket method such as Socket.AcceptAsync, Socket.ReceiveAsync, or Socket.SendAsync, an instance of SocketAsyncResult is created internally to manage the operation's state. The asynchronous methods return an object that implements the IAsyncResult interface, and this object is typically an instance of SocketAsyncResult.
The IAsyncResult interface provides a standard way to track the progress of asynchronous operations. The SocketAsyncResult class provides the specific implementation details for socket operations.
SocketAsyncResult objects. Rely on the methods provided by the Socket class to perform asynchronous socket operations.
Example Usage (Conceptual)
The following code snippet illustrates how asynchronous socket operations are initiated, and how the results are handled. Note that SocketAsyncResult is used internally and not directly accessed in this example.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class AsyncSocketExample
{
private Socket _listener;
private const int Port = 13000;
public void StartListening()
{
try
{
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listener.Bind(new IPEndPoint(IPAddress.Any, Port));
_listener.Listen(100);
Console.WriteLine($"Listening on port {Port}...");
// Start accepting connections asynchronously
var args = new SocketAsyncEventArgs();
args.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptCompleted);
_listener.AcceptAsync(args);
// Keep the main thread alive
Thread.Sleep(Timeout.Infinite);
}
catch (Exception ex)
{
Console.WriteLine($"Error starting listener: {ex.Message}");
}
}
private void AcceptCompleted(object sender, SocketAsyncEventArgs e)
{
// e is an instance of SocketAsyncEventArgs which wraps the SocketAsyncResult internally
if (e.SocketError == SocketError.Success)
{
Console.WriteLine($"Client connected: {e.AcceptSocket.RemoteEndPoint}");
// Process the accepted socket (e.g., start receiving data)
var receiveArgs = new SocketAsyncEventArgs();
receiveArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ReceiveCompleted);
// Set the buffer for receiving data
byte[] buffer = new byte[1024];
receiveArgs.SetBuffer(buffer, 0, buffer.Length);
e.AcceptSocket.ReceiveAsync(receiveArgs);
// Prepare for the next accept operation
var nextAcceptArgs = new SocketAsyncEventArgs();
nextAcceptArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptCompleted);
_listener.AcceptAsync(nextAcceptArgs);
}
else
{
Console.WriteLine($"Accept failed: {e.SocketError}");
}
e.Dispose(); // Dispose of the EventArgs object
}
private void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
string receivedData = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
Console.WriteLine($"Received: {receivedData}");
// Echo data back to client
var sendArgs = new SocketAsyncEventArgs();
sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(SendCompleted);
sendArgs.SetBuffer(e.Buffer, e.Offset, e.BytesTransferred);
e.Socket.SendAsync(sendArgs);
}
else if (e.SocketError == SocketError.ConnectionReset || e.SocketError == SocketError.Aborted)
{
Console.WriteLine($"Client disconnected.");
}
else
{
Console.WriteLine($"Receive failed: {e.SocketError}");
}
// Note: e.AcceptSocket (or e.Socket in this case) is handled by the caller or remains open until explicitly closed.
// The buffer is managed by the SocketAsyncEventArgs.
}
private void SendCompleted(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Console.WriteLine("Data sent successfully.");
}
else
{
Console.WriteLine($"Send failed: {e.SocketError}");
}
e.Dispose(); // Dispose of the EventArgs object
}
public static void Main(string[] args)
{
var example = new AsyncSocketExample();
example.StartListening();
}
}