Skip to content

Instantly share code, notes, and snippets.

@BasicPrinciples
Last active February 9, 2023 12:20
Show Gist options
  • Save BasicPrinciples/bc7500b4a8a5c41d7c1f to your computer and use it in GitHub Desktop.
Save BasicPrinciples/bc7500b4a8a5c41d7c1f to your computer and use it in GitHub Desktop.
C# Socket Async Task Extension Methods
/**
* Author: BasicPrinciples@github.com
* Date: 11/19/2015
* Namespace: SocketTasksFromAsync
* Class: SocketExtensions
* Revision: 1.0.0
* Purpose: Add tasks to the Socket class
*
* Description: Extension methods for System.Net.Sockets.Socket
* that wrap some of it's APM begin and end methods
* in tasks using Task.Factory.FromAsync<TResult>.
* Filled in documentation comments for Visual Studio.
*/
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace SocketTasksFromAsync
{
public static class SocketExtensions
{
#region Accept Tasks
/// <summary>
/// Asynchronously waits to accept an incoming connection.
/// </summary>
/// <returns>Task&lt;Socket&gt;</returns>
public static Task<Socket> AcceptTask(this Socket s)
{
return Task.Factory.FromAsync<Socket>(
s.BeginAccept(null, null),
s.EndAccept
);
}
/// <summary>
/// Asynchronously waits to accept an incoming connection.
/// </summary>
/// <param name="receiveSize">The number of bytes to accept from the sender</param>
/// <returns>Task&lt;Socket&gt;</returns>
public static Task<Socket> AcceptTask(this Socket s, int receiveSize)
{
return Task.Factory.FromAsync<Socket>(
s.BeginAccept(receiveSize, null, null),
s.EndAccept
);
}
/// <summary>
/// Asynchronously waits to accept an incoming connection.
/// </summary>
/// <param name="acceptSocket">The accepted System.Net.Sockets.Socket object, nullable.</param>
/// <param name="receiveSize">The number of bytes to accept from the sender</param>
/// <returns>Task&lt;Socket&gt;</returns>
public static Task<Socket> AcceptTask(this Socket s, Socket acceptSocket, int receiveSize)
{
return Task.Factory.FromAsync<Socket>(
s.BeginAccept(acceptSocket, receiveSize, null, null),
s.EndAccept
);
}
#endregion
#region Connect Tasks
/// <summary>
/// Makes an asynchronous request for a remote host connection
/// </summary>
/// <param name="remoteEp">
/// A System.Net.EndPoint that represents the remote host
/// </param>
/// <returns>Task</returns>
public static Task ConnectTask(this Socket s, EndPoint remoteEp)
{
return Task.Factory.FromAsync(
s.BeginConnect(remoteEp, null, null),
s.EndConnect
);
}
/// <summary>
/// Makes an asynchronous request for a remote host connection.
/// The host is specified by an IPAddress and port number.
/// </summary>
/// <param name="address">The IPAddress of the remote host</param>
/// <param name="port">The port of the remote host</param><
/// <returns>Task</returns>
public static Task ConnectTask(this Socket s, IPAddress address, int port)
{
return Task.Factory.FromAsync(
s.BeginConnect(address, port, null, null),
s.EndConnect
);
}
/// <summary>
/// Makes an asynchronous request for a remote host connection.
/// The host is specified by an IPAddress array and a port number.
/// </summary>
/// <param name="address">Array if IpAddresses of the remote host</param>
/// <param name="port">The port of the remote host</param>
/// <returns>Task</returns>
public static Task ConnectTask(this Socket s, IPAddress[] addresses, int port)
{
return Task.Factory.FromAsync(
s.BeginConnect(addresses, port, null, null),
s.EndConnect
);
}
/// <summary>
/// Makes an asynchronous request for a remote host connection.
/// The host is specified by a hostname and port number
/// </summary>
/// <param name="host">The name of the remote host</param>
/// <param name="port">The port of the remote host</param>
/// <returns>Task</returns>
public static Task ConnectTask(this Socket s, string host, int port)
{
return Task.Factory.FromAsync(
s.BeginConnect(host, port, null, null),
s.EndConnect
);
}
#endregion
#region Disconnect Tasks
/// <summary>
/// Asynchronously requests to disconnect from a remote endpoint.
/// </summary>
/// <param name="resuseSocket">Re-use the socket after connection is closed</param>
/// <returns>Task</returns>
public static Task DisconnectTask(this Socket s, bool resuseSocket)
{
return Task.Factory.FromAsync(
s.BeginDisconnect(resuseSocket, null, null),
s.EndDisconnect
);
}
#endregion
#region Receive Tasks
/// <summary>
/// Asynchronously receives data from a connected System.Net.Sockets.Socket
/// </summary>
/// <param name="buffers">
/// An array of type System.Byte that is the storage location for the received data
/// </param>
/// <param name="flags">
/// A bitwise combination of the System.Net.Sockets.SocketFlags values
/// </param>
/// <returns>Task&lt;int&gt;</returns>
public static Task<int> ReceiveTask(this Socket s, IList<ArraySegment<byte>> buffers, SocketFlags flags)
{
return Task.Factory.FromAsync<int>(
s.BeginReceive(buffers, flags, null, null),
s.EndReceive
);
}
/// <summary>
/// Asynchronously receives data from a connected System.Net.Sockets.Socket
/// </summary>
/// <param name="buffer">
/// An array of type System.Byte that is the storage location for the received data
/// </param>
/// <param name="offset">
/// The zero-based position in the buffer parameter at which to store the received data
/// </param>
/// <param name="size">The number of bytes to receive</param>
/// <param name="flags">A bitwise combination of the System.Net.Sockets.SocketFlags values</param>
/// <returns>Task&lt;int&gt;</returns>
public static Task<int> ReceiveTask(this Socket s, byte[] buffer, int offset, int size, SocketFlags flags)
{
return Task.Factory.FromAsync<int>(
s.BeginReceive(buffer, offset, size, flags, null, null),
s.EndReceive
);
}
#endregion
#region Send Tasks
/// <summary>
/// Sends data asynchronously to a connected System.Net.Sockets.Socket
/// </summary>
/// <param name="buffers">
/// An array of type System.Byte that contains the data to send
/// </param>
/// <param name="flags">A bitwise combination of the System.Net.Sockets.SocketFlags values</param>
/// <returns>Task&lt;int&gt;</returns>
public static Task<int> SendTask(this Socket s, IList<ArraySegment<byte>> buffers, SocketFlags flags)
{
return Task.Factory.FromAsync<int>(
s.BeginSend(buffers, flags, null, null),
s.EndSend
);
}
/// <summary>
/// Sends data asynchronously to a connected System.Net.Sockets.Socket
/// </summary>
/// <param name="buffer">
/// An array of type System.Byte that contains the data to send
/// </param>
/// <param name="offset">
/// The zero-based position in the buffer parameter at which to begin sending data
/// </param>
/// <param name="size">The number of bytes to send</param>
/// <param name="flags">A bitwise combination of the System.Net.Sockets.SocketFlags values</param>
/// <returns>Task&lt;int&gt;</returns>
public static Task<int> SendTask(this Socket s, byte[] buffer, int offset, int size, SocketFlags flags)
{
return Task.Factory.FromAsync<int>(
s.BeginSend(buffer, offset, size, flags, null, null),
s.EndSend
);
}
#endregion
#region SendFile Tasks
/// <summary>
/// Sends the file fileName to a connected Socket object using the UseDefaultWorkerThread flag.
/// </summary>
/// <param name="fileName">
/// A string that contains the path and name of the file to send. This parameter can be null.
/// </param>
/// <returns>Task</returns>
public static Task SendFileTask(this Socket s, string fileName)
{
return Task.Factory.FromAsync(
s.BeginSendFile(fileName, null, null),
s.EndSendFile
);
}
/// <summary>
/// Sends the file fileName to a connected Socket object using the UseDefaultWorkerThread flag.
/// </summary>
/// <param name="fileName">
/// A string that contains the path and name of the file to send. This parameter can be null.
/// </param>
/// <param name="preBuffer">
/// A Byte array that contains data to be sent before the file is sent. This parameter can be null.
/// </param>
/// <param name="postBuffer">
/// A Byte array that contains data to be sent after the file is sent. This parameter can be null.
/// </param>
/// <param name="flags">A bitwise combination of TransmitFileOptions values.</param>
/// <returns>Task</returns>
public static Task SendFileTask(this Socket s, string fileName, byte[] preBuffer,
byte[] postBuffer, TransmitFileOptions flags)
{
return Task.Factory.FromAsync(
s.BeginSendFile(fileName, preBuffer, postBuffer, flags, null, null),
s.EndSendFile
);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment