초기 커밋.
This commit is contained in:
972
JWH/NETWORK/AsyncSocket.cs
Normal file
972
JWH/NETWORK/AsyncSocket.cs
Normal file
@@ -0,0 +1,972 @@
|
||||
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
|
||||
|
||||
}
|
||||
}
|
||||
305
JWH/NETWORK/FtpClient.cs
Normal file
305
JWH/NETWORK/FtpClient.cs
Normal file
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JWH.NETWORK
|
||||
{
|
||||
|
||||
public class FtpClient
|
||||
{
|
||||
|
||||
#region [ Properties ] ------------------------------------------------
|
||||
|
||||
public string URI { get; set; }
|
||||
|
||||
public string UID { get; set; }
|
||||
|
||||
public string PWD { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ FtpClient ] -------------------------------------------------
|
||||
|
||||
public FtpClient()
|
||||
{
|
||||
}
|
||||
|
||||
public FtpClient(string uri, string uid, string pwd)
|
||||
{
|
||||
this.URI = uri;
|
||||
this.UID = uid;
|
||||
this.PWD = pwd;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ----------------------------------------------------
|
||||
|
||||
private FtpWebRequest GetFtpWebRequest(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
FtpWebRequest ftpRequest = WebRequest.Create(path) as FtpWebRequest;
|
||||
ftpRequest.Timeout = 3000;
|
||||
if (string.IsNullOrEmpty(this.UID)) ftpRequest.Credentials = new NetworkCredential();
|
||||
else ftpRequest.Credentials = new NetworkCredential(this.UID, this.PWD);
|
||||
|
||||
return ftpRequest;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetList(string path = "")
|
||||
{
|
||||
StreamReader reader = null;
|
||||
try
|
||||
{
|
||||
List<string> lstFile = new List<string>();
|
||||
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
//ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = new StreamReader(response.GetResponseStream());
|
||||
string fileInfo = reader.ReadLine();
|
||||
while (string.IsNullOrEmpty(fileInfo) == false)
|
||||
{
|
||||
object obj = this.CreateFtpObject(fileInfo);
|
||||
lstFile.Add(fileInfo);
|
||||
fileInfo = reader.ReadLine();
|
||||
}
|
||||
|
||||
return lstFile.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public FtpObject[] GetFtpObjects(string path = "")
|
||||
{
|
||||
StreamReader reader = null;
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
try
|
||||
{
|
||||
List<FtpObject> lstObject = new List<FtpObject>();
|
||||
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
//ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = new StreamReader(response.GetResponseStream());
|
||||
string fileInfo = reader.ReadLine();
|
||||
while (string.IsNullOrEmpty(fileInfo) == false)
|
||||
{
|
||||
FtpObject obj = this.CreateFtpObject(fileInfo);
|
||||
lstObject.Add(obj);
|
||||
fileInfo = reader.ReadLine();
|
||||
}
|
||||
|
||||
return lstObject.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Download(string path, string localpath)
|
||||
{
|
||||
FileStream writer = null;
|
||||
Stream reader = null;
|
||||
try
|
||||
{
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = response.GetResponseStream();
|
||||
|
||||
if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(localpath)) == false)
|
||||
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(localpath));
|
||||
writer = new FileStream(localpath, FileMode.Create, FileAccess.Write);
|
||||
byte[] byteBuffer = new byte[1024];
|
||||
|
||||
int byteSize = reader.Read(byteBuffer, 0, byteBuffer.Length);
|
||||
while (byteSize > 0)
|
||||
{
|
||||
writer.Write(byteBuffer, 0, byteSize);
|
||||
byteSize = reader.Read(byteBuffer, 0, byteBuffer.Length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Error($"{this.URI}{path} --> {localpath}");
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null) writer.Close();
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public FtpObject CreateFtpObject(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
string strDateTime = value.Substring(0, 17).Trim();
|
||||
string strType = value.Substring(18, 11).Trim();
|
||||
string strLength = value.Substring(30, 8).Trim();
|
||||
string strName = value.Substring(39).Trim();
|
||||
|
||||
DateTime dtCreate = DateTime.MinValue;
|
||||
DateTime.TryParse(strDateTime, out dtCreate);
|
||||
long nLength = 0;
|
||||
long.TryParse(strLength, out nLength);
|
||||
|
||||
FtpObject result = null;
|
||||
if (string.Compare(strType, "<DIR>", true) == 0)
|
||||
{
|
||||
FtpDirectory ftpDirectory = new FtpDirectory();
|
||||
ftpDirectory.Name = strName;
|
||||
ftpDirectory.CreateDateTime = dtCreate;
|
||||
result = ftpDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
FtpFile ftpFile = new FtpFile();
|
||||
ftpFile.Name = strName;
|
||||
ftpFile.Length = nLength;
|
||||
ftpFile.CreateDateTime = dtCreate;
|
||||
result = ftpFile;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FtpObject
|
||||
{
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
public string FullName { get { return $"{this.Path}/{this.Name}"; } }
|
||||
|
||||
public DateTime CreateDateTime { get; set; } = DateTime.MinValue;
|
||||
|
||||
public TreeNode GetTreeNode()
|
||||
{
|
||||
TreeNode node = null;
|
||||
node = new TreeNode(this.Name, 0, 0);
|
||||
node.Tag = this;
|
||||
|
||||
if (this.GetType() == typeof(FtpDirectory))
|
||||
{
|
||||
node.ImageIndex = 1;
|
||||
FtpDirectory ftpDirectory = this as FtpDirectory;
|
||||
foreach(FtpObject obj in ftpDirectory.Childs )
|
||||
{
|
||||
node.Nodes.Add(obj.GetTreeNode());
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public void Refresh(FtpClient ftpClient, int depth = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class FtpDirectory : FtpObject
|
||||
{
|
||||
|
||||
public List<FtpObject> Childs { get; set; } = new List<FtpObject>();
|
||||
|
||||
public FtpObject[] GetChilds(FtpClient ftpClient, int depth = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<FtpObject> lstChild = new List<FtpObject>();
|
||||
if (depth < 0) return lstChild.ToArray();
|
||||
|
||||
foreach (FtpObject obj in ftpClient.GetFtpObjects(this.FullName))
|
||||
{
|
||||
obj.Path = this.FullName;
|
||||
lstChild.Add(obj);
|
||||
FtpDirectory ftpDirectory = obj as FtpDirectory;
|
||||
if (ftpDirectory != null && depth > 0)
|
||||
ftpDirectory.Childs.AddRange(this.GetChilds(ftpClient, depth - 1));
|
||||
}
|
||||
|
||||
this.Childs.Clear();
|
||||
this.Childs.AddRange(lstChild.ToArray());
|
||||
|
||||
return this.Childs.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FtpFile : FtpObject
|
||||
{
|
||||
|
||||
public long Length { get; set; } = 0;
|
||||
|
||||
public FtpFile()
|
||||
{
|
||||
}
|
||||
|
||||
public FtpFile(string name, long length)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Length = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user