I've made some modifications to the async client example found on MSDN for the purpose of testing a server application.
It works entirely as I expect and/or want, even running multiple clients, but as I intend to use this as the foundation of the actual client and not just for testing I figured I'd see if I'm doing anything wrong or if anything could be optimized.
My main point of concern here being the usage of Task.Run
to initialize the send and receive functions for the client. I've seen instances that suggest using the Task.Factory
is something I want to avoid unless needed and I've seen instances that suggest Task.Factory.FromAsync
is what I want to use. Even then, I've only seen FromAsync
being proposed with BeginSend
, so I'm also not sure if this applies to BeginRecieve
as well.
While most of it is from msdn, I've had past issues with examples. Having said that, if you see anything else that stands out to you, please feel free to point that out to me as well.
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Threading.Tasks;
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
private const int port = 11000;
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
private static String response = String.Empty;
public static void Main(String[] args)
{
StartClient();
}
private static void StartClient()
{
try
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Socket client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
Task.Run(() => Receive(client));
Task.Run(() => StartTest(client));
Console.Read();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void StartTest(Socket client)
{
for (int i = 0; i <= 3000; i++)
{
Send(client, string.Format
("This Is A Test Message ({0})<|>", i));
sendDone.WaitOne();
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
state.sb.Append
(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
Console.WriteLine(state.sb.ToString()); state.sb.Clear();
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
Console.WriteLine("Sending: " + data);
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}