973 lines
29 KiB
C#
973 lines
29 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
|
|
namespace JWH.NETWORK
|
|
{
|
|
|
|
/// <summary>
|
|
/// AsyncSocket
|
|
/// <para/>비동기 통신으로 개발 되었으므로, 이벤트 수신시 크로스스레드 오류가 발생할 수 있으므로 대응코드를 작성하여야 합니다.
|
|
/// </summary>
|
|
public class AsyncSocket : IDisposable
|
|
{
|
|
|
|
#region [ Events ] ====================================================
|
|
public delegate void AsyncSocketEventHandler(AsyncSocket sender, AsyncSocketEventArgs arg);
|
|
|
|
/// <summary>AsyncSocket Accept Event (Host)</summary>
|
|
public event AsyncSocketEventHandler OnAccept;
|
|
/// <summary>AsyncSocket Connect Event</summary>
|
|
public event AsyncSocketEventHandler OnConnect;
|
|
/// <summary>AsyncSocket Close Event</summary>
|
|
public event AsyncSocketEventHandler OnClose;
|
|
/// <summary>AsyncSocket Send Event</summary>
|
|
public event AsyncSocketEventHandler OnSend;
|
|
/// <summary>AsyncSocket Receive Event</summary>
|
|
public event AsyncSocketEventHandler OnReceive;
|
|
/// <summary>AsyncSocket Error Event</summary>
|
|
public event AsyncSocketEventHandler OnError;
|
|
#endregion
|
|
|
|
#region [ Variable ] ==================================================
|
|
/// <summary>Socket</summary>
|
|
private Socket m_Socket = null;
|
|
/// <summary>Host/Remote IPAddress</summary>
|
|
private string m_Address = string.Empty;
|
|
/// <summary>Port</summary>
|
|
private int m_Port = 5000;
|
|
/// <summary>Socket Name</summary>
|
|
private string m_Name = string.Empty;
|
|
#endregion
|
|
|
|
#region [ Properties ] ================================================
|
|
|
|
/// <summary>
|
|
/// Socket
|
|
/// </summary>
|
|
public Socket Socket
|
|
{
|
|
get { return this.m_Socket; }
|
|
set { this.m_Socket = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Host/Remote IPAddress
|
|
/// </summary>
|
|
public string Address
|
|
{
|
|
get { return this.m_Address; }
|
|
set { this.m_Address = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Port
|
|
/// </summary>
|
|
public int Port
|
|
{
|
|
get { return m_Port; }
|
|
set { m_Port = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Name
|
|
/// </summary>
|
|
public string Name
|
|
{
|
|
get { return this.m_Name; }
|
|
set { this.m_Name = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Host 연결상태
|
|
/// </summary>
|
|
public bool Connected
|
|
{
|
|
get { return (m_Socket == null ? false : m_Socket.Connected); }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Constructors ] ==============================================
|
|
|
|
/// <summary>
|
|
/// AsyncSocket
|
|
/// </summary>
|
|
public AsyncSocket()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// AsyncSocket
|
|
/// </summary>
|
|
/// <param name="remoteAddress">Host</param>
|
|
/// <param name="port">Port</param>
|
|
public AsyncSocket(string remoteAddress, int port)
|
|
{
|
|
try
|
|
{
|
|
this.m_Address = remoteAddress;
|
|
this.m_Port = port;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// AsyncSocket
|
|
/// </summary>
|
|
/// <param name="socket">Socket</param>
|
|
public AsyncSocket(Socket socket)
|
|
{
|
|
try
|
|
{
|
|
this.m_Socket = socket;
|
|
try
|
|
{
|
|
IPEndPoint endpoint = (IPEndPoint)this.m_Socket.RemoteEndPoint;
|
|
this.m_Address = endpoint.Address.ToString();
|
|
this.m_Port = endpoint.Port;
|
|
}
|
|
catch
|
|
{
|
|
IPEndPoint endpoint = (IPEndPoint)this.m_Socket.LocalEndPoint;
|
|
this.m_Address = endpoint.Address.ToString();
|
|
this.m_Port = endpoint.Port;
|
|
}
|
|
|
|
if (this.m_Socket != null && this.m_Socket.IsBound)
|
|
{
|
|
this.Receive();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 구성요소를 초기화합니다
|
|
/// </summary>
|
|
public void InitializeComponent()
|
|
{
|
|
try
|
|
{
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 사용 중인 모든 리소스를 정리합니다
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
if (m_Socket != null)
|
|
{
|
|
if (m_Socket.Connected == true) this.Close();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ToString
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override string ToString()
|
|
{
|
|
try
|
|
{
|
|
if (this.m_Socket == null) return this.Name;
|
|
|
|
string strValue = string.Empty;
|
|
try
|
|
{
|
|
strValue = string.Format("{0}:{1}", this.m_Socket.RemoteEndPoint.ToString(), this.Name);
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
strValue = string.Format("{0}:{1}", this.m_Socket.LocalEndPoint.ToString(), this.Name);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
return strValue;
|
|
}
|
|
catch
|
|
{
|
|
return this.Name;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 지정한 개체 인스턴스가 동일한지를 확인합니다.
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj == null) return false;
|
|
|
|
AsyncSocket temp = obj as AsyncSocket;
|
|
if (temp == null) return false;
|
|
|
|
if (temp.Name != this.Name) return false;
|
|
if (temp.m_Address != this.Address) return false;
|
|
if (temp.Port != this.Port) return false;
|
|
if (temp.Socket != this.Socket) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 기본 해시 함수로 작동합니다.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Methods ] ===================================================
|
|
|
|
#region [ Raise_Event ] -----------------------------------------------
|
|
|
|
/// <summary>
|
|
/// OnAccept 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnAccept(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnAccept?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// OnConnect 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnConnect(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnConnect?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// OnClose 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnClose(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnClose?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// OnSend 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnSend(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnSend?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// OnReceive 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnReceive(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnReceive?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// OnError 이벤트를 전단합니다.
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected virtual void Raise_OnError(AsyncSocketEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
this.OnError?.Invoke(this, e);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Connect ] ---------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Connect
|
|
/// </summary>
|
|
public void Connect()
|
|
{
|
|
try
|
|
{
|
|
if (this.m_Socket != null && this.m_Socket.Connected == true) return;
|
|
|
|
IPAddress[] ipAddress = Dns.GetHostAddresses(this.m_Address);
|
|
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
|
|
if (this.m_Socket == null)
|
|
{
|
|
this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
this.m_Socket.ReceiveBufferSize = AsyncObject.BUFFER_SIZE;
|
|
}
|
|
|
|
this.m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(this.OnConnectCallback), this.m_Socket);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connect
|
|
/// </summary>
|
|
/// <param name="hostAddress"></param>
|
|
/// <param name="port"></param>
|
|
public void Connect(string hostAddress, int port)
|
|
{
|
|
try
|
|
{
|
|
if (this.m_Socket != null && this.m_Socket.Connected == true) return;
|
|
|
|
this.m_Address = hostAddress;
|
|
this.m_Port = port;
|
|
this.Connect();
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connect Callback
|
|
/// </summary>
|
|
/// <param name="ar"></param>
|
|
protected void OnConnectCallback(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
Socket client = (Socket)ar.AsyncState;
|
|
client.EndConnect(ar);
|
|
|
|
// OnConnect 이벤트를 날린다.
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
|
this.Raise_OnConnect(arg);
|
|
this.Receive();
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Close ] -----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Close
|
|
/// </summary>
|
|
public void Close()
|
|
{
|
|
try
|
|
{
|
|
if (this.m_Socket.Connected == true)
|
|
{
|
|
this.m_Socket.Shutdown(SocketShutdown.Both);
|
|
this.m_Socket.BeginDisconnect(false, new AsyncCallback(OnCloseCallback), this.m_Socket);
|
|
}
|
|
else
|
|
{
|
|
this.m_Socket.Close(100);
|
|
this.m_Socket = null;
|
|
}
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close Callback
|
|
/// </summary>
|
|
/// <param name="ar"></param>
|
|
protected void OnCloseCallback(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
Socket client = (Socket)ar.AsyncState;
|
|
|
|
// OnClose 이벤트를 전송한다
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
|
this.Raise_OnClose(arg);
|
|
|
|
if (client.IsBound)
|
|
{
|
|
client.EndDisconnect(ar);
|
|
client.Close();
|
|
}
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Send ] ------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Send
|
|
/// </summary>
|
|
/// <param name="buffer"></param>
|
|
public void Send(byte[] buffer, object tag = null)
|
|
{
|
|
try
|
|
{
|
|
this.m_Socket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(OnSendCallback), this.m_Socket);
|
|
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Bytes = buffer;
|
|
arg.Tag = tag;
|
|
this.Raise_OnSend(arg);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send
|
|
/// </summary>
|
|
/// <param name="buffer"></param>
|
|
/// <param name="offset"></param>
|
|
/// <param name="size"></param>
|
|
public void Send(byte[] buffer, int offset, int size, object tag = null)
|
|
{
|
|
try
|
|
{
|
|
this.m_Socket.BeginSend(buffer, offset, size, 0, new AsyncCallback(OnSendCallback), this.m_Socket);
|
|
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Bytes = buffer.Clone(offset, size);
|
|
arg.Tag = tag;
|
|
this.Raise_OnSend(arg);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send
|
|
/// </summary>
|
|
/// <param name="buffer"></param>
|
|
public void Send(string buffer, object tag = null)
|
|
{
|
|
try
|
|
{
|
|
byte[] byteBuffer = Encoding.ASCII.GetBytes(buffer);
|
|
this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);
|
|
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Bytes = byteBuffer;
|
|
arg.Tag = tag;
|
|
this.Raise_OnSend(arg);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send
|
|
/// </summary>
|
|
/// <param name="buffer"></param>
|
|
public void Send(string buffer, Encoding encoding, object tag = null)
|
|
{
|
|
try
|
|
{
|
|
byte[] byteBuffer = encoding.GetBytes(buffer);
|
|
this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);
|
|
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Bytes = byteBuffer;
|
|
arg.Tag = tag;
|
|
this.Raise_OnSend(arg);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
arg.Tag = tag;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send Callback
|
|
/// </summary>
|
|
/// <param name="ar"></param>
|
|
protected void OnSendCallback(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
Socket client = (Socket)ar.AsyncState;
|
|
int bytesWritten = client.EndSend(ar);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Receive ] ---------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Recive
|
|
/// </summary>
|
|
public void Receive()
|
|
{
|
|
try
|
|
{
|
|
AsyncObject stateObject = new AsyncObject(this.m_Socket);
|
|
this.m_Socket.BeginReceive(stateObject.Buffer, 0, AsyncObject.BUFFER_SIZE, 0, new AsyncCallback(this.OnReceiveCallback), stateObject);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Receive Callback
|
|
/// </summary>
|
|
/// <param name="ar"></param>
|
|
protected void OnReceiveCallback(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
AsyncObject stateObject = ar.AsyncState as AsyncObject;
|
|
Socket client = stateObject.Socket;
|
|
int nLength = client.EndReceive(ar);
|
|
|
|
if (nLength == 0)
|
|
{
|
|
this.Close();
|
|
return;
|
|
}
|
|
|
|
// OnReceive 이벤트를 전송한다
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
|
arg.Bytes = stateObject.Buffer.Clone(0, nLength);
|
|
this.Raise_OnReceive(arg);
|
|
this.Receive();
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Listen ] ----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Listen (Host)
|
|
/// </summary>
|
|
/// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
|
|
public void Listen(int backlog = 100)
|
|
{
|
|
try
|
|
{
|
|
IPAddress[] ipAddress = Dns.GetHostAddresses(m_Address);
|
|
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
|
|
if (this.m_Socket == null)
|
|
{
|
|
this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
this.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
|
}
|
|
this.m_Socket.Bind(ipEndPoint);
|
|
this.m_Socket.Listen(backlog);
|
|
this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Listen
|
|
/// </summary>
|
|
/// <param name="hostAddress">Host</param>
|
|
/// <param name="port">Port</param>
|
|
/// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
|
|
public void Listen(string hostAddress, int port, int backlog = 100)
|
|
{
|
|
try
|
|
{
|
|
this.m_Address = hostAddress;
|
|
this.m_Port = port;
|
|
this.Listen(backlog);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Accept ] ----------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Accept CallBack
|
|
/// </summary>
|
|
/// <param name="ar"></param>
|
|
protected void OnAcceptCallback(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
if (this.m_Socket == null) return;
|
|
Socket listener = (Socket)ar.AsyncState;
|
|
if (!listener.IsBound) return;
|
|
|
|
Socket client = listener.EndAccept(ar);
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
|
this.Raise_OnAccept(arg);
|
|
this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
|
|
}
|
|
catch (SocketException exa)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = exa;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
|
arg.Exception = ex;
|
|
this.Raise_OnError(arg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// AsyncSocket Event Argument
|
|
/// </summary>
|
|
public class AsyncSocketEventArgs : EventArgs
|
|
{
|
|
|
|
#region [ Variable ] ==================================================
|
|
/// <summary>Socket</summary>
|
|
private Socket m_Socket = null;
|
|
/// <summary>Send/Receive Data</summary>
|
|
private byte[] m_Bytes = null;
|
|
/// <summary>Tag</summary>
|
|
private object m_Tag = null;
|
|
/// <summary>Exception</summary>
|
|
private Exception m_Exception = null;
|
|
#endregion
|
|
|
|
#region [ Properties ] ================================================
|
|
|
|
/// <summary>
|
|
/// Socket
|
|
/// </summary>
|
|
public Socket Socket
|
|
{
|
|
get { return this.m_Socket; }
|
|
set { this.m_Socket = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send/Receive Data
|
|
/// </summary>
|
|
public byte[] Bytes
|
|
{
|
|
get { return this.m_Bytes; }
|
|
set { this.m_Bytes = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exception
|
|
/// </summary>
|
|
public Exception Exception
|
|
{
|
|
get { return this.m_Exception; }
|
|
set { this.m_Exception = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tag
|
|
/// </summary>
|
|
public object Tag
|
|
{
|
|
get { return this.m_Tag; }
|
|
set { this.m_Tag = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Constructors ] ==============================================
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
public AsyncSocketEventArgs()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="socket">Socket</param>
|
|
public AsyncSocketEventArgs(Socket socket)
|
|
{
|
|
m_Socket = socket;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 비동기 작업의 상태
|
|
/// </summary>
|
|
public class AsyncObject
|
|
{
|
|
|
|
#region [ Variables ] =================================================
|
|
/// <summary>버퍼사이즈</summary>
|
|
public static int BUFFER_SIZE = 32768;
|
|
/// <summary>Socket</summary>
|
|
private Socket m_Socket;
|
|
/// <summary>Buffer</summary>
|
|
private byte[] m_byteBuffer;
|
|
#endregion
|
|
|
|
#region [ Properties ] ================================================
|
|
|
|
/// <summary>
|
|
/// Socket
|
|
/// </summary>
|
|
public Socket Socket
|
|
{
|
|
get { return this.m_Socket; }
|
|
set { this.m_Socket = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 버퍼
|
|
/// </summary>
|
|
public byte[] Buffer
|
|
{
|
|
get { return this.m_byteBuffer; }
|
|
set { this.m_byteBuffer = value; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Constructors ] ==============================================
|
|
|
|
/// <summary>
|
|
/// AsyncObject
|
|
/// </summary>
|
|
/// <param name="socket">Socket</param>
|
|
public AsyncObject(Socket socket)
|
|
{
|
|
try
|
|
{
|
|
this.m_Socket = socket;
|
|
this.m_byteBuffer = new byte[BUFFER_SIZE];
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
XLogger.Instance.Fatal(ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|