class EasySocket
{
public delegate void ConnectEvent(object sender);
public delegate void ShutdownEvent(object sender);
public delegate void ClientConnectedEvent(Socket socketConnected, object sender);
public delegate void DataReceivedEvent(String data, Socket fromSocket, object sender);
public delegate void DataSendEvent(object sender);
public enum FamilyType
{
Tcp,
Udp
}
public class Server : IDisposable
{
public Server()
{
EndToken = "\0";
}
public event ClientConnectedEvent OnClientConnected;
public event DataReceivedEvent OnDataReceive;
public event DataSendEvent OnDataSent;
public event ShutdownEvent OnShutdown;
public FamilyType SocketFamilyType { get; set; }
public int Port { get; set; }
public int MaxClient { get; set; }
public bool Universal { get; set; }
public String EndToken { get; set; }
public bool Started { get; private set; }
public List<Socket> SocketsConnected { get { return this.m_Sockets; } }
public void Start()
{
if (String.IsNullOrEmpty(SocketFamilyType.ToString()) || Port == 0)
return;
else // I liked this style
{
m_EndPoint = new IPEndPoint(Universal ? IPAddress.Any : IPAddress.Loopback, Port);
switch (SocketFamilyType)
{
case FamilyType.Tcp:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
break;
case FamilyType.Udp:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
break;
}
try
{
m_Socket.Bind(m_EndPoint);
m_Socket.Listen(MaxClient);
m_Socket.BeginAccept(CallBack_OnAccept, m_Socket);
Started = true;
}
catch (SocketException ex)
{
throw new Exception(String.Format("Port {0} has already been occupied.", Port));
}
}
}
public void Disconnnect(Socket trySocket)
{
if (trySocket != null)
{
try
{
trySocket.BeginDisconnect(true, CallBack_OnDisconnect, trySocket);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
public void Send(Socket socket, String data)
{
data += EndToken;
byte[] byteData = Encoding.ASCII.GetBytes(data);
socket.BeginSend(byteData, 0, byteData.Length, 0, CallBack_OnSend, socket);
}
public void Broadcast(String data)
{
foreach (var m_Socket_field in m_Sockets)
Send(m_Socket_field, data);
}
public void Shutdown()
{
m_Socket.Close();
if (this.OnShutdown != null) OnShutdown(this);
this.Dispose();
}
private void CallBack_OnAccept(IAsyncResult ar)
{
Socket socketAccepted = null;
try
{
socketAccepted = m_Socket.EndAccept(ar);
m_Sockets.Add(socketAccepted);
m_SocketsBuffer.Add(socketAccepted, new StringBuilder());
if (OnClientConnected != null)
OnClientConnected(socketAccepted, this);
socketAccepted.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, CallBack_OnReceive, socketAccepted);
m_Socket.BeginAccept(CallBack_OnAccept, m_Socket);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Disconnnect(socketAccepted);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private void CallBack_OnReceive(IAsyncResult ar)
{
Socket socketAccepted = null;
try
{
socketAccepted = ar.AsyncState as Socket;
int read = socketAccepted.EndReceive(ar);
var sb = new StringBuilder();
if (read > 0)
{
String strRead = Encoding.ASCII.GetString(m_Data, 0, read);
char lastChar = strRead[strRead.Length - 1];
//Console.WriteLine("{0}", strRead);
Console.WriteLine("{0}", m_SocketsBuffer[socketAccepted]);
if (lastChar != '\r' )
{
m_SocketsBuffer[socketAccepted].Append(strRead);
socketAccepted.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, CallBack_OnReceive, socketAccepted);
return;
}
sb.Append(m_SocketsBuffer[socketAccepted]);
//socketAccepted.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, CallBack_OnReceive, socketAccepted);
}
if (sb.Length > 0)
{
string content = sb.ToString();
if (!String.IsNullOrEmpty(EndToken))
{
int index = content.IndexOf(EndToken, StringComparison.Ordinal);
if (index != -1)
content = content.Substring(0, index);
}
if (OnDataReceive != null)
OnDataReceive(content, socketAccepted, this);
// Flush it
m_SocketsBuffer[socketAccepted] = new StringBuilder();
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Disconnnect(socketAccepted);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private void CallBack_OnSend(IAsyncResult ar)
{
Socket socketAccepted = null;
try
{
socketAccepted = ar.AsyncState as Socket;
// Complete sending the data to the remote device.
socketAccepted.EndSend(ar);
if (this.OnDataSent != null)
OnDataSent(this);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Disconnnect(socketAccepted);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private void CallBack_OnDisconnect(IAsyncResult ar)
{
try
{
Socket socketTryDisconnect = ar.AsyncState as Socket;
socketTryDisconnect.EndDisconnect(ar);
m_SocketsBuffer.Remove(socketTryDisconnect);
m_Sockets.Remove(socketTryDisconnect);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private readonly Dictionary<Socket, StringBuilder> m_SocketsBuffer = new Dictionary<Socket, StringBuilder>();
private List<Socket> m_Sockets = new List<Socket>();
private byte[] m_Data = new byte[65535];
private IPEndPoint m_EndPoint;
private Socket m_Socket;
public void Dispose()
{
m_Data = null;
m_Socket = null;
m_Sockets = null;
m_EndPoint = null;
GC.Collect();
GC.SuppressFinalize(this);
}
}
public class Client : IDisposable
{
public event ConnectEvent OnConnected;
public event DataReceivedEvent OnDataReceive;
public event DataSendEvent OnDataSent;
public event ShutdownEvent OnShutdown;
public FamilyType SocketFamilyType { get; set; }
public string Destination { get; set; }
public int Port { get; set; }
public String EndToken { get; set; }
public bool Conntected { get { return m_Socket.Connected; } }
public void Connect()
{
if (String.IsNullOrEmpty(SocketFamilyType.ToString()) || Port == 0)
return;
else // I liked this style
{
m_EndPoint = new IPEndPoint(Array.Find(Dns.GetHostAddresses(Destination), a => a.AddressFamily == AddressFamily.InterNetwork), Port);
switch (SocketFamilyType)
{
case FamilyType.Tcp:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
break;
case FamilyType.Udp:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
break;
}
m_Socket.BeginConnect(m_EndPoint, CallBack_OnConnected, m_Socket);
}
}
public void Send(String data)
{
data += EndToken;
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
m_Socket.BeginSend(byteData, 0, byteData.Length, 0, CallBack_OnSend, m_Socket);
}
public void Shutdown()
{
m_Socket.Shutdown(SocketShutdown.Receive);
if (this.OnShutdown != null) OnShutdown(this);
this.Dispose();
}
private void CallBack_OnSend(IAsyncResult ar)
{
try
{
m_Socket.EndSend(ar);
if (this.OnDataSent != null)
OnDataSent(this);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private void CallBack_OnConnected(IAsyncResult ar)
{
try
{
m_Socket.EndConnect(ar);
if (OnConnected != null)
OnConnected(this);
m_Socket.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, CallBack_OnReceive, m_Socket);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private void CallBack_OnReceive(IAsyncResult ar)
{
try
{
Socket socketAccepted = ar.AsyncState as Socket;
int read = socketAccepted.EndReceive(ar);
var sb = new StringBuilder();
if (read > 0)
{
sb.Append(Encoding.ASCII.GetString(m_Data, 0, read));
socketAccepted.BeginReceive(m_Data, 0, m_Data.Length, SocketFlags.None, CallBack_OnReceive, socketAccepted);
}
if (sb.Length > 0)
{
string content = sb.ToString();
if (!String.IsNullOrEmpty(EndToken))
{
int index = content.IndexOf(EndToken);
if (index != -1)
content = content.Substring(0, index);
}
if (OnDataReceive != null)
OnDataReceive(content, socketAccepted, this);
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
private IPEndPoint m_EndPoint;
private byte[] m_Data = new byte[65535];
private Socket m_Socket;
public void Dispose()
{
this.m_Data = null;
this.m_Socket = null;
this.m_EndPoint = null;
GC.Collect();
GC.SuppressFinalize(this);
}
}
}