[성현모] CPXV2 Init

This commit is contained in:
SHM
2024-06-26 10:30:00 +09:00
parent cdf12248c5
commit 5958993b6a
588 changed files with 698420 additions and 0 deletions

View File

@ -0,0 +1,940 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
using SystemX.Net.Comm;
using static SystemX.Net.Platform.Common.Util.LogMessage;
namespace SystemX.Net.Comm
{
public class AsyncClientSocket : SystemXSocket, IDisposable
{
private Socket ClientSock; /* client Socket */
private Socket cbClientSock; /* client Async Callback Socket */
private byte[] recvBuffer;
//private String recvText;
private byte[] recvStoreBuffer;
private int iStoreCnt;
private int iCheckRetryCnt;
private const int MAX_CHECK_COUNT = 100; /* 256000 / 4096 <- 65526 / 4096 */
private const int USER_MAX_SIZE = 819200; /* 256000 <- 1000000 65536 */
private const int MAXSIZE = 8192; /* 8192 <- 4096 */
private const int MAX_PACKET_COUNT = 1024;
private string m_strGetIp;
private int m_iGetPort;
private bool m_bConnected;
private string m_strGetText;
private bool m_bGetRecv;
private bool bDisposed;
private bool bReadySocket;
public override event SocketCallEvent Comm_Connect_Event;
public override event SocketCallEvent Socket_Error_Event;
public override event SendRecvCallEvent Comm_Send_Event;
public override event SendRecvCallEvent Comm_Recv_Event;
public override event EventHandler<ScheduleEvent> AwaitSendEvent;
public override event EventHandler<ScheduleEvent> AwaitRecvEvent;
private Queue<CPacketDataInfo> QPacketAllData;
private Queue<CPacketDataInfo> QPacketRemainData;
private bool bQueuePacketClearOn;
public override void SetRefSocketPacketClear()
{
bQueuePacketClearOn = true;
}
/*
private Task taskPacketCaclQueue;
private bool m_bThreadPCQBlock;
//
private CancellationTokenSource CTS;
private CancellationToken CT;
//
private async void WatchPacketCaclQueue()
{
await Task.Delay(250).ConfigureAwait(false);
while (!m_bThreadPCQBlock)
{
try
{
CT.ThrowIfCancellationRequested();
}
catch (OperationCanceledException CancelEx)
{
MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @" Work Canceled. [SystemX.Net.Comm : AsyncClientSocket.WatchPacketCaclQueue]\r\n" + CancelEx.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
break;
}
//
try
{
}
catch (Exception e)
{
MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"General Queue Schedule failed. [SystemX.Net.Comm : AsyncClientSocket.WatchPacketCaclQueue]\r\n" + e.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
}
await Task.Delay(1).ConfigureAwait(false);
}
}
*/
public bool CONNECT
{
get { return this.m_bConnected; }
}
public string MSG
{
set { this.m_strGetText = value; }
get { return this.m_strGetText; }
}
public bool RECV_STATE
{
set { this.m_bGetRecv = value; }
get { return this.m_bGetRecv; }
}
public bool READY_STATE
{
set { this.bReadySocket = value; }
get { return this.bReadySocket; }
}
public string strGetLocalAddress { set; get; }
public string strGetLocalPort { set; get; }
public AsyncClientSocket(SOCKET_TYPE SOCK_TYPE, IPEndPoint SetRemote) : base(SOCKET_RULE.CLIENT, SOCK_TYPE)
{
nSocketNumber = 100;
bDisposed = false;
QPacketAllData = new Queue<CPacketDataInfo>();
QPacketRemainData = new Queue<CPacketDataInfo>();
bQueuePacketClearOn = false;
bReadySocket = false;
m_strGetIp = SetRemote.Address.ToString();
m_iGetPort = SetRemote.Port;
ClientSock = null;
cbClientSock = null;
//recvText = string.Empty;
recvStoreBuffer = new byte[USER_MAX_SIZE];
iStoreCnt = 0;
iCheckRetryCnt = 0;
recvBuffer = new byte[MAXSIZE];
//
m_bGetRecv = false;
m_bConnected = false;
AwaitSendEvent += SendCompleteEvent;
/*
taskSendQueue = null;
m_bThreadSendBlock = false;
taskSendQueue = new Task(new Action(WatchSendQueue));
taskSendQueue.Start();
*/
bReadySocket = DoReady();
/*
//
CTS = new CancellationTokenSource();
CT = CTS.Token;
//
m_bThreadPCQBlock = false;
taskPacketCaclQueue = new Task(new Action(WatchPacketCaclQueue), CT);
taskPacketCaclQueue.Start();
//
*/
}
private async void WatchSendQueue()
{
/*
while (!m_bThreadSendBlock)
{
try
{
if(qSendData.Count > 0)
{
byte[] ucGetData;
if(qSendData.TryDequeue(out ucGetData))
{
cbClientSock.BeginSend(ucGetData, 0, ucGetData.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucGetData);
stopWaitHandle.WaitOne();
}
}
}
catch (Exception e)
{
ErrorEventProcess(new CommonSocketException("Send error.[SystemX.Net.Comm : AsyncClientSocket|WatchSendQueue]"));
}
await Task.Delay(1);
}
*/
await Task.Delay(1);
}
public void ClearEventConnectCall()
{
if (Comm_Connect_Event != null)
{
foreach (Delegate d in Comm_Connect_Event.GetInvocationList())
Comm_Connect_Event -= (SocketCallEvent)d;
}
}
public void ClearEventErrorCall()
{
if (Socket_Error_Event != null)
{
foreach (Delegate d in Socket_Error_Event.GetInvocationList())
Socket_Error_Event -= (SocketCallEvent)d;
}
}
public void ClearEventSendCall()
{
if (Comm_Send_Event != null)
{
foreach (Delegate d in Comm_Send_Event.GetInvocationList())
Comm_Send_Event -= (SendRecvCallEvent)d;
}
}
public void ClearEventRecvCall()
{
if (Comm_Recv_Event != null)
{
foreach (Delegate d in Comm_Recv_Event.GetInvocationList())
Comm_Recv_Event -= (SendRecvCallEvent)d;
}
}
public void ClearEventAsyncSendCall()
{
if (AwaitSendEvent != null)
{
foreach (Delegate d in AwaitSendEvent.GetInvocationList())
AwaitSendEvent -= (EventHandler<ScheduleEvent>)d;
}
}
public void ClearEventAsyncRecvCall()
{
if (AwaitRecvEvent != null)
{
foreach (Delegate d in AwaitRecvEvent.GetInvocationList())
AwaitRecvEvent -= (EventHandler<ScheduleEvent>)d;
}
}
protected override void Dispose(bool disposing)
{
if (!bDisposed)
{
try
{
/*
if (taskSendQueue != null)
{
m_bThreadSendBlock = true;
taskSendQueue.Wait();
}
*/
// dispose managed resource (종결자를 가진 객체의 자원 해제)
/*
if (cbClientSock != null)
{
if (cbClientSock.Connected)
{
cbClientSock.Disconnect(false);
cbClientSock.Shutdown(SocketShutdown.Both);
cbClientSock.Close();
cbClientSock = null;
}
cbClientSock = null;
}
*/
if (ClientSock != null)
{
if (ClientSock.Connected)
{
ClientSock.Disconnect(false);
ClientSock.Shutdown(SocketShutdown.Both);
}
ClientSock.Close();
ClientSock = null;
}
/*if(cbClientSock != null)
cbClientSock.Close();*/
cbClientSock = null;
m_bConnected = false;
}
catch
{
cbClientSock = null;
ClientSock = null;
m_bConnected = false;
ErrorEventProcess(new Exception("Dispose failed. [SystemX.Net.Comm : AsyncClientSocket.Dispose]"));
}
finally
{
ClearEventAsyncSendCall();
ClearEventAsyncRecvCall();
ClearEventSendCall();
ClearEventRecvCall();
/*
ClearEventConnectCall();
ClearEventErrorCall();
*/
}
if (disposing)
{
//Manage
}
//Unmanage
recvStoreBuffer = null;
recvBuffer = null;
bDisposed = true;
}
//Base Dispose
base.Dispose(disposing);
}
private void ErrorEventProcess(Exception e, bool ConnectStateOff = false)
{
//if (e.SocketErrorCode == SocketError.NotConnected)
m_bConnected = ConnectStateOff;
Socket_Error_Event?.Invoke(e, new ScheduleEvent(nSocketNumber, false, "Error", 0));
}
private bool DoReady()
{
bool bDoState = true;
try
{
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
LingerOption SetLinger = new LingerOption(true, 1);
ClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
//ClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 90000,
KeepAliveInterval = 3000
};
int iState = ClientSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
}
}
catch (Exception e)
{
bDoState = false;
/* 접속 실패 */
ErrorEventProcess(e);
}
finally
{
;//
}
return bDoState;
}
public void Connect()
{
if (bReadySocket)
BeginConnect();
}
private void BeginConnect()
{
try
{
/* 접속 대기중 */
ClientSock.BeginConnect(m_strGetIp, m_iGetPort, new AsyncCallback(ConnectCallBack), ClientSock);
}
catch (Exception e)
{
/* 접속 실패 */
ErrorEventProcess(e);
}
}
private void ConnectCallBack(IAsyncResult IAR)
{
try
{
//보류중인 연결을 완성
Socket tempSock = (Socket)IAR.AsyncState;
IPEndPoint svrEP = (IPEndPoint)tempSock.RemoteEndPoint;
IPEndPoint connEP = (IPEndPoint)tempSock.LocalEndPoint;
string strLocalAddress = connEP.Address.ToString();
string strLocalPort = connEP.Port.ToString();
strGetLocalAddress = strLocalAddress;
strGetLocalPort = strLocalPort;
tempSock.EndConnect(IAR);
//AsyncSocketObject objScoket = new AsyncSocketObject(MAXSIZE);
//objScoket.WorkSocket = tempSock;
cbClientSock = tempSock;// objScoket.WorkSocket;
/*
LingerOption SetLinger = new LingerOption(true, 1);
cbClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
cbClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 53000,
KeepAliveInterval = 2000
};
int iState = cbClientSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
*/
//데이터 받을 이벤트 함수 등록
cbClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
m_bConnected = true;
Comm_Connect_Event?.BeginInvoke(ClientSock, new ScheduleEvent(nSocketNumber, true, "Connect", 0), InvokeCallback, null);
}
catch (Exception e)
{
/* 접속 실패 */
ErrorEventProcess(e);
}
}
private void InvokeCallback(object obj)
{
}
public override bool BeginSend(byte[] ucDatas)
{
bool bState = true;
if (cbClientSock == null)
return false;
//qSendData.Enqueue(ucDatas);
try
{
//연결 성공시
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
cbClientSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(Socket SetSock, byte[] ucDatas)
{
bool bState = true;
if (cbClientSock == null)
return false;
try
{
//연결 성공시
if (SetSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
SetSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(string strMessage)
{
bool bState = true;
if (cbClientSock == null)
return false;
try
{
//연결 성공시
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
byte[] buffer = new UnicodeEncoding().GetBytes(strMessage);
cbClientSock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), strMessage);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
private void SendCallBack(IAsyncResult IAR)
{
//전송 완료
byte[] getData = null;
ScheduleEvent se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
if (cbClientSock == null)
return;
bool bResult = true;
try
{
getData = (byte[])IAR.AsyncState;
if (getData != null)
se = new ScheduleEvent(nSocketNumber, true, "Send Success", 0);
else
se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
finally
{
if (bResult)
{
Comm_Send_Event?.BeginInvoke(getData, se, null, null);
AwaitSendEvent?.BeginInvoke(getData, se, null, null);
//Comm_Send_Event?.Invoke(getData, se);
//AwaitSendEvent?.Invoke(getData, se);
}
}
//
try
{
int iSendCnt = cbClientSock.EndSend(IAR);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
}
private void SendCompleteEvent(object senderData, ScheduleEvent e)
{
}
private void Receive()
{
if (cbClientSock == null)
return;
//받기
try
{
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
cbClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), cbClientSock);
}
catch (Exception e)
{
ErrorEventProcess(e);
}
}
private void OnReceiveCallBack(IAsyncResult IAR)
{
bool bReceiveState = true;
int nReadSize = 0;
Socket ClientSideSock = null;
//AsyncSocketObject objScoket = null;
try
{
//수신
ClientSideSock = (Socket)IAR.AsyncState;
//objScoket = (AsyncSocketObject)IAR.AsyncState;
}
catch (Exception e)
{
this.Dispose(true);
//수신 실패
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
return;
}
try
{
if (ClientSideSock.Connected)
nReadSize = ClientSideSock.EndReceive(IAR);
else
{
if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
nReadSize = ClientSideSock.EndReceive(IAR);
else
bReceiveState = false;
}
}
catch (Exception e)
{
bReceiveState = false;
}
//
if (bReceiveState)
{
if (nReadSize != 0)
{
byte[] ucFindData = new byte[1];
//byte[] ucSetClearArray;
int iFindDataCnt = 0;
//bool bSegmentFind = false;
bool bDataFind = false;
byte ucGetLabel = 0;
try
{
/*
Array.Copy(recvBuffer, 0, recvStoreBuffer, iStoreCnt, nReadSize);
iStoreCnt += nReadSize;
*/
if (bQueuePacketClearOn)
{
bQueuePacketClearOn = false;
QPacketAllData.Clear();
}
//
QPacketAllData.Enqueue(new CPacketDataInfo(DateTime.Now, recvBuffer, nReadSize));
foreach (var n in QPacketAllData.ToList())
{
TimeSpan dsInterval = DateTime.Now - n.dtPacket;
//오랜된 패킷 소거
if (dsInterval.TotalSeconds >= 20.0)
QPacketAllData.Dequeue();
else
QPacketRemainData.Enqueue(new CPacketDataInfo(n.ID, n.dtPacket, n.ucData, n.nDataSize));
}
//
iStoreCnt = 0;
Array.Clear(recvStoreBuffer, 0, USER_MAX_SIZE);
Guid[] guidUsePacketID = new Guid[QPacketRemainData.Count];
int nPacketPos = 0;
//남은 패킷중 연산 시도
foreach (var n in QPacketRemainData.ToList())
{
Array.Copy(n.ucData, 0, recvStoreBuffer, iStoreCnt, n.nDataSize);
iStoreCnt += n.nDataSize;
guidUsePacketID[nPacketPos++] = n.ID;
for (int j = 0; j < iStoreCnt; j++)
{
if (recvStoreBuffer[j] == 0x0D &&
recvStoreBuffer[j + 1] == 0x02 &&
recvStoreBuffer[j + 6] == 0x08 &&
recvStoreBuffer[j + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[j - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[j + iGetSize - 4] == 0x0D &&
recvStoreBuffer[j + iGetSize - 3] == 0x02 &&
recvStoreBuffer[j + iGetSize - 2] == 0x08 &&
recvStoreBuffer[j + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
ucFindData = new byte[iFindDataCnt];
Array.Copy(recvStoreBuffer, j, ucFindData, 0, iFindDataCnt);
bDataFind = true;
break;
}
else
{
bDataFind = false;
break;
}
}
}
//
if(bDataFind)
{
//성공한 패킷이 있을경우 해당 패킷 제거
foreach (var m in QPacketAllData.ToList())
{
for (int i = 0; i < guidUsePacketID.Count(); i++)
{
if (m.ID == guidUsePacketID[i])
{
QPacketAllData.Dequeue();
break;
}
}
}
break;
}
}
QPacketRemainData.Clear();
//recvText += Encoding.Unicode.GetString(recvBuffer, 0, nReadSize);
/*
for (int i = 0; i < iStoreCnt; i++)
{
if (recvStoreBuffer[i] == 0x0D &&
recvStoreBuffer[i + 1] == 0x02 &&
recvStoreBuffer[i + 6] == 0x08 &&
recvStoreBuffer[i + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[i - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[i + iGetSize - 4] == 0x0D &&
recvStoreBuffer[i + iGetSize - 3] == 0x02 &&
recvStoreBuffer[i + iGetSize - 2] == 0x08 &&
recvStoreBuffer[i + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
bSegmentFind = true;
}
if (bSegmentFind)
{
iCheckRetryCnt = 0;
ucFindData = new byte[iFindDataCnt];
ucSetClearArray = new byte[(iFindDataCnt + 1)];
Array.Clear(ucSetClearArray, 0, (iFindDataCnt + 1));
Array.Copy(recvStoreBuffer, i, ucFindData, 0, iFindDataCnt);
iStoreCnt -= (iFindDataCnt + 1);
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, (iFindDataCnt + 1));
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
bDataFind = true;
break;
}
else
{
iCheckRetryCnt++;
if (iCheckRetryCnt > MAX_CHECK_COUNT)
{
iCheckRetryCnt = 0;
ucSetClearArray = new byte[iFindDataCnt];
Array.Clear(ucSetClearArray, 0, iFindDataCnt);
iStoreCnt -= iFindDataCnt;
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, iFindDataCnt);
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
}
break;
}
}
}
*/
}
catch (Exception e)
{
bDataFind = false;
/*
iStoreCnt = 0;
if(recvStoreBuffer != null) Array.Clear(recvStoreBuffer, 0, recvStoreBuffer.Count());
*/
}
if (bDataFind)
{
bool bDataControl = true;
byte[] ucGetInfp = null;
try
{
ucGetInfp = new byte[iFindDataCnt];
Array.Copy(ucFindData, ucGetInfp, iFindDataCnt);
}
catch (Exception e)
{
bDataControl = false;
}
ScheduleEvent se = null;
m_bGetRecv = true;
//recvText = string.Empty;
if (bDataControl)
{
se = new ScheduleEvent(nSocketNumber, true, "Recv Success", ucGetLabel);
}
else
{
se = new ScheduleEvent(nSocketNumber, false, "Recv Fail", ucGetLabel);
}
Comm_Recv_Event?.BeginInvoke(ucGetInfp, se, null, null);
AwaitRecvEvent?.BeginInvoke(ucGetInfp, se, null, null);
//Comm_Recv_Event?.Invoke(ucGetInfp, se);
//AwaitRecvEvent?.Invoke(ucGetInfp, se);
}
this.Receive();
//objScoket.WorkSocket.BeginReceive(objScoket.recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), objScoket);
}
else
{
this.Dispose(true);
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
}
}
else
{
this.Dispose(true);
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
}
}
}
}

View File

@ -0,0 +1,871 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
using SystemX.Net.Comm;
namespace SystemX.Net.Comm
{
public class AsyncComClientSocket : SystemXSocket, IDisposable
{
private Socket ClientSock; /* client Socket */
private Socket cbClientSock; /* client Async Callback Socket */
private byte[] recvBuffer;
//private String recvText;
private byte[] recvStoreBuffer;
private int iStoreCnt;
private int iCheckRetryCnt;
private const int MAX_CHECK_COUNT = 100; /* 256000 / 4096 <- 65526 / 4096 */
private const int USER_MAX_SIZE = 819200; /* 256000 <- 1000000 65536 */
private const int MAXSIZE = 8192; /* 8192 <- 4096 */
private string m_strGetIp;
private int m_iGetPort;
private bool m_bConnected;
private string m_strGetText;
private bool m_bGetRecv;
private bool bDisposed;
public override event SocketCallEvent Comm_Connect_Event;
public override event SocketCallEvent Socket_Error_Event;
public override event SendRecvCallEvent Comm_Send_Event;
public override event SendRecvCallEvent Comm_Recv_Event;
public override event EventHandler<ScheduleEvent> AwaitSendEvent;
public override event EventHandler<ScheduleEvent> AwaitRecvEvent;
private Queue<CPacketDataInfo> QPacketAllData;
private Queue<CPacketDataInfo> QPacketRemainData;
private bool bQueuePacketClearOn;
public override void SetRefSocketPacketClear()
{
bQueuePacketClearOn = true;
}
/*
private Task taskSendQueue;
private bool m_bThreadSendBlock;
private ConcurrentQueue<byte[]> qSendData = new ConcurrentQueue<byte[]>();
AutoResetEvent stopWaitHandle = new AutoResetEvent(false);
*/
public bool CONNECT
{
get { return this.m_bConnected; }
}
public string MSG
{
set { this.m_strGetText = value; }
get { return this.m_strGetText; }
}
public bool RECV_STATE
{
set { this.m_bGetRecv = value; }
get { return this.m_bGetRecv; }
}
public string strGetLocalAddress { set; get; }
public string strGetLocalPort { set; get; }
public AsyncComClientSocket(SOCKET_TYPE SOCK_TYPE, IPEndPoint SetRemote) : base(SOCKET_RULE.CLIENT, SOCK_TYPE)
{
nSocketNumber = 100;
bDisposed = false;
QPacketAllData = new Queue<CPacketDataInfo>();
QPacketRemainData = new Queue<CPacketDataInfo>();
bQueuePacketClearOn = false;
m_strGetIp = SetRemote.Address.ToString();
m_iGetPort = SetRemote.Port;
ClientSock = null;
cbClientSock = null;
//recvText = string.Empty;
recvStoreBuffer = new byte[USER_MAX_SIZE];
iStoreCnt = 0;
iCheckRetryCnt = 0;
recvBuffer = new byte[MAXSIZE];
//
m_bGetRecv = false;
m_bConnected = false;
AwaitSendEvent += SendCompleteEvent;
/*
taskSendQueue = null;
m_bThreadSendBlock = false;
taskSendQueue = new Task(new Action(WatchSendQueue));
taskSendQueue.Start();
*/
this.DoInit();
}
private async void WatchSendQueue()
{
/*
while (!m_bThreadSendBlock)
{
try
{
if(qSendData.Count > 0)
{
byte[] ucGetData;
if(qSendData.TryDequeue(out ucGetData))
{
cbClientSock.BeginSend(ucGetData, 0, ucGetData.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucGetData);
stopWaitHandle.WaitOne();
}
}
}
catch (Exception e)
{
ErrorEventProcess(new CommonSocketException("Send error.[SystemX.Net.Comm : AsyncClientSocket|WatchSendQueue]"));
}
await Task.Delay(1);
}
*/
await Task.Delay(1);
}
public void ClearEventConnectCall()
{
if (Comm_Connect_Event != null)
{
foreach (Delegate d in Comm_Connect_Event.GetInvocationList())
Comm_Connect_Event -= (SocketCallEvent)d;
}
}
public void ClearEventErrorCall()
{
if (Socket_Error_Event != null)
{
foreach (Delegate d in Socket_Error_Event.GetInvocationList())
Socket_Error_Event -= (SocketCallEvent)d;
}
}
public void ClearEventSendCall()
{
if (Comm_Send_Event != null)
{
foreach (Delegate d in Comm_Send_Event.GetInvocationList())
Comm_Send_Event -= (SendRecvCallEvent)d;
}
}
public void ClearEventRecvCall()
{
if (Comm_Recv_Event != null)
{
foreach (Delegate d in Comm_Recv_Event.GetInvocationList())
Comm_Recv_Event -= (SendRecvCallEvent)d;
}
}
public void ClearEventAsyncSendCall()
{
if (AwaitSendEvent != null)
{
foreach (Delegate d in AwaitSendEvent.GetInvocationList())
AwaitSendEvent -= (EventHandler<ScheduleEvent>)d;
}
}
public void ClearEventAsyncRecvCall()
{
if (AwaitRecvEvent != null)
{
foreach (Delegate d in AwaitRecvEvent.GetInvocationList())
AwaitRecvEvent -= (EventHandler<ScheduleEvent>)d;
}
}
protected override void Dispose(bool disposing)
{
if (!bDisposed)
{
AwaitSendEvent -= SendCompleteEvent;
try
{
/*
if (taskSendQueue != null)
{
m_bThreadSendBlock = true;
taskSendQueue.Wait();
}
*/
// dispose managed resource (종결자를 가진 객체의 자원 해제)
/*
if (cbClientSock != null)
{
if (cbClientSock.Connected)
{
cbClientSock.Disconnect(false);
cbClientSock.Shutdown(SocketShutdown.Both);
cbClientSock.Close();
cbClientSock = null;
}
cbClientSock = null;
}
*/
if (ClientSock != null)
{
if (ClientSock.Connected)
{
ClientSock.Disconnect(false);
ClientSock.Shutdown(SocketShutdown.Both);
ClientSock.Close();
ClientSock = null;
}
ClientSock = null;
}
/*if(cbClientSock != null)
cbClientSock.Close();*/
cbClientSock = null;
m_bConnected = false;
}
catch
{
cbClientSock = null;
ClientSock = null;
m_bConnected = false;
ErrorEventProcess(new Exception("Dispose failed. [SystemX.Net.Comm : AsyncComClientSocket.Dispose]"));
}
finally
{
ClearEventAsyncSendCall();
ClearEventAsyncRecvCall();
ClearEventSendCall();
ClearEventRecvCall();
/*
ClearEventConnectCall();
ClearEventErrorCall();
*/
}
if (disposing)
{
//Manage
}
//Unmanage
recvStoreBuffer = null;
recvBuffer = null;
bDisposed = true;
}
//Base Dispose
base.Dispose(disposing);
}
private void ErrorEventProcess(Exception e, bool ConnectStateOff = false)
{
//if (e.SocketErrorCode == SocketError.NotConnected)
m_bConnected = ConnectStateOff;
Socket_Error_Event?.Invoke(e, new ScheduleEvent(nSocketNumber, false, "Error", 0));
}
private void DoInit()
{
bool bDoState = true;
try
{
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
ClientSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
LingerOption SetLinger = new LingerOption(true, 1);
ClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
//ClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 90000,
KeepAliveInterval = 3000
};
int iState = ClientSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
}
}
catch (Exception e)
{
bDoState = false;
/* 접속 실패 */
ErrorEventProcess(e);
}
finally
{
if (bDoState)
this.BeginConnect();
}
}
private void BeginConnect()
{
try
{
/* 접속 대기중 */
ClientSock.BeginConnect(m_strGetIp, m_iGetPort, new AsyncCallback(ConnectCallBack), ClientSock);
}
catch (Exception e)
{
/* 접속 실패 */
ErrorEventProcess(e);
}
}
private void ConnectCallBack(IAsyncResult IAR)
{
try
{
//보류중인 연결을 완성
Socket tempSock = (Socket)IAR.AsyncState;
IPEndPoint svrEP = (IPEndPoint)tempSock.RemoteEndPoint;
IPEndPoint connEP = (IPEndPoint)tempSock.LocalEndPoint;
string strLocalAddress = connEP.Address.ToString();
string strLocalPort = connEP.Port.ToString();
strGetLocalAddress = strLocalAddress;
strGetLocalPort = strLocalPort;
tempSock.EndConnect(IAR);
//AsyncSocketObject objScoket = new AsyncSocketObject(MAXSIZE);
//objScoket.WorkSocket = tempSock;
cbClientSock = tempSock;
/*
LingerOption SetLinger = new LingerOption(true, 1);
cbClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
cbClientSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 53000,
KeepAliveInterval = 2000
};
int iState = cbClientSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
*/
//데이터 받을 이벤트 함수 등록
cbClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
m_bConnected = true;
Comm_Connect_Event?.BeginInvoke(ClientSock, new ScheduleEvent(nSocketNumber, true, "Connect", 0), InvokeCallback, null);
}
catch (Exception e)
{
/* 접속 실패 */
ErrorEventProcess(e);
}
}
private void InvokeCallback(object obj)
{
}
public override bool BeginSend(byte[] ucDatas)
{
bool bState = true;
if (cbClientSock == null)
return false;
//qSendData.Enqueue(ucDatas);
try
{
//연결 성공시
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
cbClientSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(Socket SetSock, byte[] ucDatas)
{
bool bState = true;
if (cbClientSock == null)
return false;
try
{
//연결 성공시
if (SetSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
SetSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(string strMessage)
{
bool bState = true;
if (cbClientSock == null)
return false;
try
{
//연결 성공시
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
byte[] buffer = new UnicodeEncoding().GetBytes(strMessage);
cbClientSock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), strMessage);
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
private void SendCallBack(IAsyncResult IAR)
{
//전송 완료
byte[] getData = null;
ScheduleEvent se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
if (cbClientSock == null)
return;
bool bResult = true;
try
{
getData = (byte[])IAR.AsyncState;
if (getData != null)
se = new ScheduleEvent(nSocketNumber, true, "Send Success", 0);
else
se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
finally
{
if (bResult)
{
Comm_Send_Event?.BeginInvoke(getData, se, null, null);
AwaitSendEvent?.BeginInvoke(getData, se, null, null);
//Comm_Send_Event?.Invoke(getData, se);
//AwaitSendEvent?.Invoke(getData, se);
}
}
try
{
int iSendCnt = cbClientSock.EndSend(IAR);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
}
private void SendCompleteEvent(object senderData, ScheduleEvent e)
{
}
private void Receive()
{
if (cbClientSock == null)
return;
//받기
try
{
if (cbClientSock.Connected || base.SOCK_TYPE == SOCKET_TYPE.UDP)
cbClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
}
catch (Exception e)
{
ErrorEventProcess(e);
}
}
private void OnReceiveCallBack(IAsyncResult IAR)
{
bool bReceiveState = true;
int nReadSize = 0;
Socket ClientSideSock = null;
//AsyncSocketObject objScoket = null;
try
{
//수신
ClientSideSock = (Socket)IAR.AsyncState;
//objScoket = (AsyncSocketObject)IAR.AsyncState;
}
catch (Exception e)
{
this.Dispose(true);
//수신 실패
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
return;
}
try
{
if (ClientSideSock.Connected)
nReadSize = ClientSideSock.EndReceive(IAR);
else
{
if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
nReadSize = ClientSideSock.EndReceive(IAR);
else
bReceiveState = false;
}
}
catch (Exception e)
{
bReceiveState = false;
}
//
if (bReceiveState)
{
if (nReadSize != 0)
{
byte[] ucFindData = new byte[1];
//byte[] ucSetClearArray;
int iFindDataCnt = 0;
//bool bSegmentFind = false;
bool bDataFind = false;
byte ucGetLabel = 0;
try
{
/*
Array.Copy(recvBuffer, 0, recvStoreBuffer, iStoreCnt, nReadSize);
iStoreCnt += nReadSize;
*/
if (bQueuePacketClearOn)
{
bQueuePacketClearOn = false;
QPacketAllData.Clear();
}
QPacketAllData.Enqueue(new CPacketDataInfo(DateTime.Now, recvBuffer, nReadSize));
foreach (var n in QPacketAllData.ToList())
{
TimeSpan dsInterval = DateTime.Now - n.dtPacket;
//오랜된 패킷 소거
if (dsInterval.TotalSeconds >= 20.0)
QPacketAllData.Dequeue();
else
QPacketRemainData.Enqueue(new CPacketDataInfo(n.ID, n.dtPacket, n.ucData, n.nDataSize));
}
//
iStoreCnt = 0;
Array.Clear(recvStoreBuffer, 0, USER_MAX_SIZE);
Guid[] guidUsePacketID = new Guid[QPacketRemainData.Count];
int nPacketPos = 0;
//남은 패킷중 연산 시도
foreach (var n in QPacketRemainData.ToList())
{
Array.Copy(n.ucData, 0, recvStoreBuffer, iStoreCnt, n.nDataSize);
iStoreCnt += n.nDataSize;
guidUsePacketID[nPacketPos++] = n.ID;
for (int j = 0; j < iStoreCnt; j++)
{
if (recvStoreBuffer[j] == 0x0D &&
recvStoreBuffer[j + 1] == 0x02 &&
recvStoreBuffer[j + 6] == 0x08 &&
recvStoreBuffer[j + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[j - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[j + iGetSize - 4] == 0x0D &&
recvStoreBuffer[j + iGetSize - 3] == 0x02 &&
recvStoreBuffer[j + iGetSize - 2] == 0x08 &&
recvStoreBuffer[j + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
ucFindData = new byte[iFindDataCnt];
Array.Copy(recvStoreBuffer, j, ucFindData, 0, iFindDataCnt);
bDataFind = true;
break;
}
else
{
bDataFind = false;
break;
}
}
}
//
if (bDataFind)
{
//성공한 패킷이 있을경우 해당 패킷 제거
foreach (var m in QPacketAllData.ToList())
{
for (int i = 0; i < guidUsePacketID.Count(); i++)
{
if (m.ID == guidUsePacketID[i])
{
QPacketAllData.Dequeue();
break;
}
}
}
break;
}
}
QPacketRemainData.Clear();
//recvText += Encoding.Unicode.GetString(recvBuffer, 0, nReadSize);
/*
for (int i = 0; i < iStoreCnt; i++)
{
if (recvStoreBuffer[i] == 0x0D &&
recvStoreBuffer[i + 1] == 0x02 &&
recvStoreBuffer[i + 6] == 0x08 &&
recvStoreBuffer[i + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[i - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[i + iGetSize - 4] == 0x0D &&
recvStoreBuffer[i + iGetSize - 3] == 0x02 &&
recvStoreBuffer[i + iGetSize - 2] == 0x08 &&
recvStoreBuffer[i + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
bSegmentFind = true;
}
if (bSegmentFind)
{
iCheckRetryCnt = 0;
ucFindData = new byte[iFindDataCnt];
ucSetClearArray = new byte[(iFindDataCnt + 1)];
Array.Clear(ucSetClearArray, 0, (iFindDataCnt + 1));
Array.Copy(recvStoreBuffer, i, ucFindData, 0, iFindDataCnt);
iStoreCnt -= (iFindDataCnt + 1);
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, (iFindDataCnt + 1));
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
bDataFind = true;
break;
}
else
{
iCheckRetryCnt++;
if (iCheckRetryCnt > MAX_CHECK_COUNT)
{
iCheckRetryCnt = 0;
ucSetClearArray = new byte[iFindDataCnt];
Array.Clear(ucSetClearArray, 0, iFindDataCnt);
iStoreCnt -= iFindDataCnt;
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, iFindDataCnt);
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
}
break;
}
}
}
*/
}
catch (Exception e)
{
bDataFind = false;
/*
iStoreCnt = 0;
if (recvStoreBuffer != null) Array.Clear(recvStoreBuffer, 0, recvStoreBuffer.Count());
*/
}
if (bDataFind)
{
bool bDataControl = true;
byte[] ucGetInfp = null;
try
{
ucGetInfp = new byte[iFindDataCnt];
Array.Copy(ucFindData, ucGetInfp, iFindDataCnt);
}
catch (Exception e)
{
bDataControl = false;
}
ScheduleEvent se = null;
m_bGetRecv = true;
//recvText = string.Empty;
if (bDataControl)
{
se = new ScheduleEvent(nSocketNumber, true, "Recv Success", ucGetLabel);
}
else
{
se = new ScheduleEvent(nSocketNumber, false, "Recv Fail", ucGetLabel);
}
Comm_Recv_Event?.BeginInvoke(ucGetInfp, se, null, null);
AwaitRecvEvent?.BeginInvoke(ucGetInfp, se, null, null);
//Comm_Recv_Event?.Invoke(ucGetInfp, se);
//AwaitRecvEvent?.Invoke(ucGetInfp, se);
}
this.Receive();
//objScoket.WorkSocket.BeginReceive(objScoket.recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), objScoket);
}
else
{
this.Dispose(true);
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
}
}
else
{
this.Dispose(true);
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncClientSocket|OnReceiveCallBack]"));
}
}
}
}

View File

@ -0,0 +1,977 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
using SystemX.Net.Comm;
//using static SystemX.Net.Platform.Common.Util.LogMessage;
namespace SystemX.Net.Comm
{
public class AsyncServerSocket : SystemXSocket, IDisposable
{
private Socket ServerSock;
private IPAddress SetAddress;
//Unused
private Socket ClientSock; /* client Socket */
//private Socket cbClientSock; /* client Async Callback Socket */
private byte[] recvBuffer;
//private String recvText;
private byte[] recvStoreBuffer;
private int iStoreCnt;
private int iCheckRetryCnt;
private const int MAX_CHECK_COUNT = 100; /* 256000 / 4096 <- 65526 / 4096 */
private const int USER_MAX_SIZE = 819200; /* 256000 <- 1000000 65536 */
private const int MAXSIZE = 8192; /* 8192 <- 4096 */
private string m_strGetIp;
private int m_iGetPort;
private bool m_bOpen;
private bool m_bConnected;
private string m_strGetText;
private bool m_bGetRecv;
public override event SocketCallEvent Comm_Connect_Event;
public override event SocketCallEvent Socket_Error_Event;
public override event SendRecvCallEvent Comm_Send_Event;
public override event SendRecvCallEvent Comm_Recv_Event;
private Queue<CPacketDataInfo> QPacketAllData;
private Queue<CPacketDataInfo> QPacketRemainData;
private bool bQueuePacketClearOn;
public override void SetRefSocketPacketClear()
{
bQueuePacketClearOn = true;
}
private bool bDisposed;
//
//private bool bHaveHostinfo;
//private DataTable dtHostInfo;
public bool STATE
{
get { return this.m_bOpen; }
}
public bool CLIENT_CONNECT
{
get { return this.m_bConnected; }
}
public string MSG
{
set { this.m_strGetText = value; }
get { return this.m_strGetText; }
}
public bool RECV_STATE
{
set { this.m_bGetRecv = value; }
get { return this.m_bGetRecv; }
}
public string strSetRemoteAddress { set; get; }
public string strSetRemotePort { set; get; }
/*
public bool HAVE_HOST_INFO
{
set { this.bHaveHostinfo = value; }
get { return this.bHaveHostinfo; }
}
*/
public AsyncServerSocket(SOCKET_TYPE SOCK_TYPE, int iCreatePosition, IPEndPoint SetRemote) : base(SOCKET_RULE.SERVER, SOCK_TYPE)
{
bDisposed = false;
QPacketAllData = new Queue<CPacketDataInfo>();
QPacketRemainData = new Queue<CPacketDataInfo>();
bQueuePacketClearOn = false;
strSetRemoteAddress = string.Empty;
strSetRemotePort = string.Empty;
SetAddress = SetRemote.Address;
nSocketNumber = iCreatePosition;
m_strGetIp = SetRemote.Address.ToString();
m_iGetPort = SetRemote.Port;
ServerSock = null;
ClientSock = null;
//cbClientSock = null;
//recvText = string.Empty;
recvStoreBuffer = new byte[USER_MAX_SIZE];
iStoreCnt = 0;
iCheckRetryCnt = 0;
recvBuffer = new byte[MAXSIZE];
//
m_bGetRecv = false;
m_bOpen = false;
m_bConnected = false;
SetSocketListen();
}
public AsyncServerSocket(SOCKET_TYPE SOCK_TYPE, int iCreatePosition, IPEndPoint SetRemote, DataTable dtHostInfomation) : base(SOCKET_RULE.SERVER, SOCK_TYPE)
{
bDisposed = false;
strSetRemoteAddress = string.Empty;
strSetRemotePort = string.Empty;
SetAddress = SetRemote.Address;
nSocketNumber = iCreatePosition;
m_strGetIp = SetRemote.Address.ToString();
m_iGetPort = SetRemote.Port;
ServerSock = null;
ClientSock = null;
//cbClientSock = null;
//recvText = string.Empty;
recvStoreBuffer = new byte[USER_MAX_SIZE];
iStoreCnt = 0;
iCheckRetryCnt = 0;
recvBuffer = new byte[MAXSIZE];
//
m_bGetRecv = false;
m_bOpen = false;
m_bConnected = false;
SetSocketListen();
}
protected override void Dispose(bool disposing)
{
if (!bDisposed)
{
ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);
try
{
if (ServerSock != null)
{
if (ServerSock.Connected)
ServerSock.Shutdown(SocketShutdown.Both);
ServerSock.Close();
//ServerSock.Dispose();
ServerSock = null;
}
m_bOpen = false;
ClientSock = null;
m_bConnected = false;
}
catch (Exception e)
{
ClientSock = null;
ServerSock = null;
m_bOpen = false;
m_bConnected = false;
ErrorEventProcess(new Exception("Dispose failed. [SystemX.Net.Comm : AsyncServerSocket.Dispose]"));
}
finally
{
/*
ClearEventConnectCall();
ClearEventErrorCall();
*/
ClearEventSendCall();
ClearEventRecvCall();
}
if (disposing)
{
//Manage
}
//Unmanage
recvStoreBuffer = null;
recvBuffer = null;
bDisposed = true;
}
//Base Dispose
base.Dispose(disposing);
}
public void ClearEventConnectCall()
{
if (Comm_Connect_Event != null)
{
foreach (Delegate d in Comm_Connect_Event.GetInvocationList())
Comm_Connect_Event -= (SocketCallEvent)d;
}
}
public void ClearEventErrorCall()
{
if (Socket_Error_Event != null)
{
foreach (Delegate d in Socket_Error_Event.GetInvocationList())
Socket_Error_Event -= (SocketCallEvent)d;
}
}
public void ClearEventSendCall()
{
if (Comm_Send_Event != null)
{
foreach (Delegate d in Comm_Send_Event.GetInvocationList())
Comm_Send_Event -= (SendRecvCallEvent)d;
}
}
public void ClearEventRecvCall()
{
if (Comm_Recv_Event != null)
{
foreach (Delegate d in Comm_Recv_Event.GetInvocationList())
Comm_Recv_Event -= (SendRecvCallEvent)d;
}
}
public void ServerSocketAllClearToken()
{
ConnectTokken.AllClearToken((ConnectTokken.Connect_Token)nSocketNumber);
}
public bool ServerTokenPosCheck(int iGet)
{
return ConnectTokken.GetTokenPosState((ConnectTokken.Connect_Token)nSocketNumber, iGet);
}
public void ServerSocketUnknownError(bool bCallEvent = true)
{
ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);
try
{
if (ClientSock != null)
{
if (ClientSock.Connected)
{
ClientSock.Disconnect(false);
ClientSock.Shutdown(SocketShutdown.Both);
ClientSock.Close();
ClientSock = null;
}
ClientSock = null;
}
//m_bOpen = false;
}
catch (Exception ex)
{
ClientSock = null;
//MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"Client socket release error.[SystemX.Net.Net.Comm.AsyncServerSocket] " + ex.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
}
m_bConnected = false;
if (bCallEvent)
Socket_Error_Event?.Invoke(null, new ScheduleEvent(nSocketNumber, false, "Error", 0));
}
private void ErrorEventProcess(Exception e, bool ConnectStateOff = false, bool bServerSock = false)
{
//if (e.SocketErrorCode == SocketError.NotConnected)
ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, false);
if (bServerSock == false)
m_bConnected = ConnectStateOff;
else
m_bOpen = ConnectStateOff;
Socket_Error_Event?.Invoke(e, new ScheduleEvent(nSocketNumber, false, "Error", 0));
}
private void AcceptCallback(IAsyncResult ar)
{
try
{
if (m_bOpen)
{
Socket SockListen = null;
try
{
SockListen = (Socket)ar?.AsyncState;
int nGetAvailable = SockListen.Available;
}
catch (ObjectDisposedException dispose)
{
SockListen = null;
throw new Exception();
}
if (SockListen != null)
{
IPEndPoint GetIPInfo = (IPEndPoint)SockListen.LocalEndPoint;
if (ConnectTokken.GetTokenState((ConnectTokken.Connect_Token)nSocketNumber) == false)
{
ConnectTokken.SetTokenState((ConnectTokken.Connect_Token)nSocketNumber, true);
//AsyncSocketObject objScoket = new AsyncSocketObject(MAXSIZE);
Socket sockClient = SockListen.EndAccept(ar);
//objScoket.WorkSocket = sockClient;
ClientSock = sockClient; // objScoket.WorkSocket;
m_bConnected = true;
sockClient.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
Comm_Connect_Event?.BeginInvoke(ClientSock, new ScheduleEvent(nSocketNumber, true, "Connect", 0), InvokeCallback, null);
}
//클라이언트의 연결 요청 대기
SockListen.BeginAccept(AcceptCallback, SockListen);
}
}
}
catch (Exception e)
{
//종료 또는 Accept 실패.
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket|AcceptCallback]"));
}
}
private void InvokeCallback(object obj)
{
}
private void SetSocketListen()
{
try
{
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
LingerOption SetLinger = new LingerOption(true, 0);
ServerSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SetLinger);
//ServerSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
var option = new TcpKeepAlive
{
OnOff = 1,
KeepAliveTime = 90000,
KeepAliveInterval = 3000
};
int iState = ServerSock.IOControl(IOControlCode.KeepAliveValues, option.GetBytes(), null);
// 서버에서 클라이언트의 연결 요청을 대기하기 위해 소켓을 열어둔다.
IPEndPoint mkServerEP;
mkServerEP = new IPEndPoint(SetAddress, m_iGetPort);
ServerSock.Bind(mkServerEP);
ServerSock.Listen(1024);
SetSocketBeginReady();
}
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
ServerSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// 서버에서 클라이언트의 연결 요청을 대기하기 위해 소켓을 열어둔다.
IPEndPoint mkServerEP;
mkServerEP = new IPEndPoint(SetAddress, m_iGetPort);
EndPoint ServerEP;
ServerEP = new IPEndPoint(SetAddress, m_iGetPort);
ServerSock.Bind(mkServerEP);
//ServerSock.BeginReceiveFrom(recvBuffer, 0, MAXSIZE, SocketFlags.None, ref ServerEP, new AsyncCallback(OnReceiveCallBack), ServerSock);
ServerSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ServerSock);
}
m_bOpen = true;
}
catch (Exception e)
{
//종료 또는 Accept 실패.
ErrorEventProcess(new CommonSocketException("Server socket open-ready fail.[SystemX.Net.Comm : AsyncServerSocket|DoInit]"), false, true);
}
}
private void SetSocketBeginReady()
{
try
{
if (ServerSock != null)
// 비동기적으로 클라이언트의 연결 요청을 받는다.
ServerSock.BeginAccept(AcceptCallback, ServerSock);
}
catch (Exception e)
{
//종료 또는 Accept 실패.
ErrorEventProcess(new CommonSocketException("Server socket BeginAccept() fail. [SystemX.Net.Comm : AsyncServerSocket|SetSocketListen]"), false, true);
}
}
public override bool BeginSend(byte[] ucDatas)
{
bool bState = true;
if (ClientSock == null)
{
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
return false;
else
{
if (ServerSock == null)
return false;
}
}
try
{
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
/* 연결 성공시 */
if (ClientSock.Connected) ClientSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
{
EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
ServerSock.BeginSendTo(ucDatas, 0, ucDatas.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), ucDatas);
}
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(Socket SetSock, byte[] ucDatas)
{
bool bState = true;
if (SetSock == null)
{
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
return false;
else
{
if (ServerSock == null)
return false;
}
}
try
{
/* 연결 성공시 */
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
if (SetSock.Connected) SetSock.BeginSend(ucDatas, 0, ucDatas.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ucDatas);
}
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
{
EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
ServerSock.BeginSendTo(ucDatas, 0, ucDatas.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), ucDatas);
}
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
public override bool BeginSend(string strMessage)
{
bool bState = true;
if (ClientSock == null)
{
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
return false;
else
{
if (ServerSock == null)
return false;
}
}
try
{
byte[] buffer = new UnicodeEncoding().GetBytes(strMessage);
/* 연결 성공시 */
if (base.SOCK_TYPE == SOCKET_TYPE.TCP)
{
if (ClientSock.Connected) ClientSock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), strMessage);
}
else if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
{
if (strSetRemoteAddress.Length > 0 && strSetRemotePort.Length > 0)
{
EndPoint setRemote = new IPEndPoint(IPAddress.Parse(strSetRemoteAddress), int.Parse(strSetRemotePort));
ServerSock.BeginSendTo(buffer, 0, buffer.Length, SocketFlags.None, setRemote, new AsyncCallback(SendCallBack), strMessage);
}
}
}
catch (Exception e)
{
bState = false;
//전송 에러
ErrorEventProcess(e);
}
return bState;
}
private void SendCallBack(IAsyncResult IAR)
{
//전송 완료
byte[] getData = null;
ScheduleEvent se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
if (ClientSock == null)
{
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
return;
else
{
if (ServerSock == null)
return;
}
}
bool bResult = true;
try
{
getData = (byte[])IAR.AsyncState;
if (getData != null)
se = new ScheduleEvent(nSocketNumber, true, "Send Success", 0);
else
se = new ScheduleEvent(nSocketNumber, false, "Send Fail", 0);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
finally
{
if (bResult)
{
Comm_Send_Event?.BeginInvoke(getData, se, null, null);
}
}
//
try
{
int iSendCnt = 0;
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
iSendCnt = ClientSock.EndSend(IAR);
else
iSendCnt = ServerSock.EndSend(IAR);
}
catch (Exception e)
{
bResult = false;
//Callback Error
ErrorEventProcess(e);
}
}
private void Receive()
{
if (ClientSock == null)
{
if (base.SOCK_TYPE != SOCKET_TYPE.UDP)
return;
else
{
if (ServerSock == null)
return;
}
}
//받기
try
{
if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
ServerSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ServerSock);
else
{
if (ClientSock.Connected)
ClientSock.BeginReceive(recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), ClientSock);
}
}
catch (Exception e)
{
ErrorEventProcess(e);
}
}
private void OnReceiveCallBack(IAsyncResult IAR)
{
bool bReceiveState = true;
int nReadSize = 0;
Socket ClientSideSock;
//AsyncSocketObject objScoket = null;
try
{
//수신
ClientSideSock = (Socket)IAR.AsyncState;
//objScoket = (AsyncSocketObject)IAR.AsyncState;
}
catch (Exception e)
{
this.Dispose();
//수신 실패
ErrorEventProcess(new CommonSocketException("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket|OnReceiveCallBack]"));
return;
}
try
{
if (ClientSideSock.Connected)
nReadSize = ClientSideSock.EndReceive(IAR);
else
{
if (base.SOCK_TYPE == SOCKET_TYPE.UDP)
nReadSize = ClientSideSock.EndReceive(IAR);
else
bReceiveState = false;
}
}
catch (Exception e)
{
bReceiveState = false;
}
//
if (bReceiveState)
{
if (nReadSize != 0)
{
byte[] ucFindData = new byte[1];
byte[] ucSetClearArray;
int iFindDataCnt = 0;
bool bSegmentFind = false;
bool bDataFind = false;
byte ucGetLabel = 0;
try
{
/*
Array.Copy(recvBuffer, 0, recvStoreBuffer, iStoreCnt, nReadSize);
iStoreCnt += nReadSize;
*/
if(bQueuePacketClearOn)
{
bQueuePacketClearOn = false;
QPacketAllData.Clear();
}
QPacketAllData.Enqueue(new CPacketDataInfo(DateTime.Now, recvBuffer, nReadSize));
foreach (var n in QPacketAllData.ToList())
{
TimeSpan dsInterval = DateTime.Now - n.dtPacket;
//오랜된 패킷 소거
if (dsInterval.TotalSeconds >= 20.0)
QPacketAllData.Dequeue();
else
QPacketRemainData.Enqueue(new CPacketDataInfo(n.ID, n.dtPacket, n.ucData, n.nDataSize));
}
//
iStoreCnt = 0;
Array.Clear(recvStoreBuffer, 0, USER_MAX_SIZE);
Guid[] guidUsePacketID = new Guid[QPacketRemainData.Count];
int nPacketPos = 0;
//남은 패킷중 연산 시도
foreach (var n in QPacketRemainData.ToList())
{
Array.Copy(n.ucData, 0, recvStoreBuffer, iStoreCnt, n.nDataSize);
iStoreCnt += n.nDataSize;
guidUsePacketID[nPacketPos++] = n.ID;
for (int j = 0; j < iStoreCnt; j++)
{
if (recvStoreBuffer[j] == 0x0D &&
recvStoreBuffer[j + 1] == 0x02 &&
recvStoreBuffer[j + 6] == 0x08 &&
recvStoreBuffer[j + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[j - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[j + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[j + iGetSize - 4] == 0x0D &&
recvStoreBuffer[j + iGetSize - 3] == 0x02 &&
recvStoreBuffer[j + iGetSize - 2] == 0x08 &&
recvStoreBuffer[j + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
ucFindData = new byte[iFindDataCnt];
Array.Copy(recvStoreBuffer, j, ucFindData, 0, iFindDataCnt);
bDataFind = true;
break;
}
else
{
bDataFind = false;
break;
}
}
}
//
if (bDataFind)
{
//성공한 패킷이 있을경우 해당 패킷 제거
foreach (var m in QPacketAllData.ToList())
{
for (int i = 0; i < guidUsePacketID.Count(); i++)
{
if (m.ID == guidUsePacketID[i])
{
QPacketAllData.Dequeue();
break;
}
}
}
break;
}
}
QPacketRemainData.Clear();
//recvText += Encoding.Unicode.GetString(recvBuffer, 0, nReadSize);
/*
for (int i = 0; i < iStoreCnt; i++)
{
if (recvStoreBuffer[i] == 0x0D &&
recvStoreBuffer[i + 1] == 0x02 &&
recvStoreBuffer[i + 6] == 0x08 &&
recvStoreBuffer[i + 7] == 0x0A)
{
ucGetLabel = recvStoreBuffer[i - 1];
uint uiGetPacketSize = 0x0;
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 2] << 24);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 3] << 16);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 4] << 8);
uiGetPacketSize |= (uint)(recvStoreBuffer[i + 5] << 0);
int iGetSize = (int)uiGetPacketSize;
iGetSize += XCommons.PAD_SIZE;
if (recvStoreBuffer[i + iGetSize - 4] == 0x0D &&
recvStoreBuffer[i + iGetSize - 3] == 0x02 &&
recvStoreBuffer[i + iGetSize - 2] == 0x08 &&
recvStoreBuffer[i + iGetSize - 1] == 0x0A)
{
iFindDataCnt = iGetSize;
bSegmentFind = true;
}
if (bSegmentFind)
{
iCheckRetryCnt = 0;
ucFindData = new byte[iFindDataCnt];
ucSetClearArray = new byte[(iFindDataCnt + 1)];
Array.Clear(ucSetClearArray, 0, (iFindDataCnt + 1));
Array.Copy(recvStoreBuffer, i, ucFindData, 0, iFindDataCnt);
iStoreCnt -= (iFindDataCnt + 1);
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, (iFindDataCnt + 1));
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
bDataFind = true;
break;
}
else
{
iCheckRetryCnt++;
if (iCheckRetryCnt > MAX_CHECK_COUNT)
{
iCheckRetryCnt = 0;
ucSetClearArray = new byte[iFindDataCnt];
Array.Clear(ucSetClearArray, 0, iFindDataCnt);
iStoreCnt -= iFindDataCnt;
Buffer.BlockCopy(ucSetClearArray, 0, recvStoreBuffer, 0, iFindDataCnt);
Buffer.BlockCopy(recvStoreBuffer, iStoreCnt, recvStoreBuffer, 0, USER_MAX_SIZE - iStoreCnt);
}
break;
}
}
}
*/
}
catch (Exception e)
{
bDataFind = false;
/*
iStoreCnt = 0;
if (recvStoreBuffer != null) Array.Clear(recvStoreBuffer, 0, recvStoreBuffer.Count());
*/
}
//
if (bDataFind)
{
bool bDataControl = true;
byte[] ucGetInfp = null;
try
{
ucGetInfp = new byte[iFindDataCnt];
Array.Copy(ucFindData, ucGetInfp, iFindDataCnt);
}
catch (Exception e)
{
bDataControl = false;
}
ScheduleEvent se = null;
m_bGetRecv = true;
//recvText = string.Empty;
if (bDataControl)
{
se = new ScheduleEvent(nSocketNumber, true, "Recv Success", ucGetLabel);
}
else
{
se = new ScheduleEvent(nSocketNumber, false, "Recv Fail", ucGetLabel);
}
Comm_Recv_Event?.BeginInvoke(ucGetInfp, se, null, null);
}
this.Receive();
//objScoket.WorkSocket.BeginReceive(objScoket.recvBuffer, 0, MAXSIZE, SocketFlags.None, new AsyncCallback(OnReceiveCallBack), objScoket);
}
else
{
this.Dispose();
ErrorEventProcess(new Exception("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket.OnReceiveCallBack]"));
}
}
else
{
this.Dispose();
ErrorEventProcess(new Exception("Middleware server side connection lost.[SystemX.Net.Comm : AsyncServerSocket.OnReceiveCallBack]"));
}
}
}
}

View File

@ -0,0 +1,383 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
namespace SystemX.Net.Comm
{
//
// 요약:
// Socket error information
public class CommonSocketException : Exception
{
public CommonSocketException()
{
}
public CommonSocketException(string message)
: base(message)
{
}
public CommonSocketException(string message, Exception inner)
: base(message, inner)
{
}
}
public enum SOCKET_RULE
{
NONE = -1,
SERVER = 0,
CLIENT = 1
}
public enum SOCKET_TYPE
{
NONE = -1,
TCP = 0,
UDP = 1
}
public class SystemXSocket : IDisposable
{
public virtual event SocketCallEvent Comm_Connect_Event;
public virtual event SocketCallEvent Socket_Error_Event;
public virtual event SendRecvCallEvent Comm_Send_Event;
public virtual event SendRecvCallEvent Comm_Recv_Event;
public virtual event EventHandler<ScheduleEvent> AwaitSendEvent;
public virtual event EventHandler<ScheduleEvent> AwaitRecvEvent;
public int nSocketNumber;
private bool bDisposed;
public SOCKET_RULE SOCK_RULE { set; get; }
public SOCKET_TYPE SOCK_TYPE { set; get; }
public SystemXSocket(SOCKET_RULE GET_SOCK_RULE, SOCKET_TYPE GET_SOCK_TYPE) {
SOCK_RULE = GET_SOCK_RULE;
SOCK_TYPE = GET_SOCK_TYPE;
bDisposed = false;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if(bDisposed == false)
{
if(bDisposing)
{
//Manage
}
//Unmanage
bDisposed = true;
}
}
~SystemXSocket()
{
Dispose(false);
}
public virtual bool BeginSend(byte[] ucDatas) { return true; }
public virtual bool BeginSend(Socket SetSock, byte[] ucDatas) { return true; }
public virtual bool BeginSend(string strMessage) { return true; }
public virtual void SetRefSocketPacketClear() { return; }
}
public class CPacketDataInfo
{
public Guid ID;
public DateTime dtPacket;
public byte[] ucData;
public int nDataSize;
public CPacketDataInfo(DateTime dateTime, byte[] ucGetData, int nGetSize)
{
if (ID == default(Guid))
ID = Guid.NewGuid();
dtPacket = dateTime;
nDataSize = nGetSize;
ucData = new byte[nGetSize];
Buffer.BlockCopy(ucGetData, 0, ucData, 0, nGetSize);
}
public CPacketDataInfo(Guid SetID, DateTime dateTime, byte[] ucGetData, int nGetSize)
{
ID = SetID;
dtPacket = dateTime;
nDataSize = nGetSize;
ucData = new byte[nGetSize];
Buffer.BlockCopy(ucGetData, 0, ucData, 0, nGetSize);
}
}
public class AsyncSocketObject
{
public byte[] recvBuffer;
public Socket WorkSocket;
public readonly int iBufferSize;
public AsyncSocketObject(int ibufferSize)
{
iBufferSize = ibufferSize;
recvBuffer = new byte[iBufferSize];
}
public void ClearBuffer()
{
Array.Clear(recvBuffer, 0, iBufferSize);
}
}
public class TcpKeepAlive
{
public uint OnOff { get; set; }
public uint KeepAliveTime { get; set; }
public uint KeepAliveInterval { get; set; }
public byte[] GetBytes()
{
return BitConverter.GetBytes(OnOff).Concat(BitConverter.GetBytes(KeepAliveTime)).Concat(BitConverter.GetBytes(KeepAliveInterval)).ToArray();
}
}
public static class ConnectTokken
{
public enum Connect_Token
{
T010 = 0,
T020 = 1,
T030 = 2,
T040 = 3,
T050 = 4,
T060 = 5,
T070 = 6,
T080 = 7,
T090 = 8,
T100 = 9,
T110 = 10,
T120 = 11,
T130 = 12,
T140 = 13,
T150 = 14,
T160 = 15,
T170 = 16,
T180 = 17,
T190 = 18,
T200 = 19,
T210 = 20,
T220 = 21,
T230 = 22,
T240 = 23,
T250 = 24,
T260 = 25,
T270 = 26,
T280 = 27,
T290 = 28,
T300 = 29,
T310 = 30,
T320 = 31,
T330 = 32,
T340 = 33,
T350 = 34,
T360 = 35,
T370 = 36,
T380 = 37,
T390 = 38,
T400 = 39,
T410 = 40,
T420 = 41,
T430 = 42,
T440 = 43,
T450 = 44,
T460 = 45,
T470 = 46,
T480 = 47,
T490 = 48,
T500 = 49,
T510 = 50,
T520 = 51,
T530 = 52,
T540 = 53,
T550 = 54,
T560 = 55,
T570 = 56,
T580 = 57,
T590 = 58,
T600 = 59,
T610 = 60,
T620 = 61,
T630 = 62,
T640 = 63,
T650 = 64,
T660 = 65,
T670 = 66,
T680 = 67,
T690 = 68,
T700 = 69,
T710 = 70,
T720 = 71,
T730 = 72,
T740 = 73,
T750 = 74,
T760 = 75,
T770 = 76,
T780 = 77,
T790 = 78,
T800 = 79,
T810 = 80,
T820 = 81,
T830 = 82,
T840 = 83,
T850 = 84,
T860 = 85,
T870 = 86,
T880 = 87,
T890 = 88,
T900 = 89,
T910 = 90,
T920 = 91,
T930 = 92,
T940 = 93,
T950 = 94,
T960 = 95,
T970 = 96,
T980 = 97,
T990 = 98,
T1000 = 99,
T1010 = 100,
T1020 = 101,
T1030 = 102,
T1040 = 103,
T1050 = 104,
T1060 = 105,
T1070 = 106,
T1080 = 107,
T1090 = 108,
T1100 = 109,
T1110 = 110,
T1120 = 111,
T1130 = 112,
T1140 = 113,
T1150 = 114,
T1160 = 115,
T1170 = 116,
T1180 = 117,
T1190 = 118,
T1200 = 119,
T1210 = 120,
T1220 = 121,
T1230 = 122,
T1240 = 123,
T1250 = 124,
T1260 = 125,
T1270 = 126,
T1280 = 127
}
public const int MAX_PROCESS_NUM = 128;
public const int MAX_TOKEN_NUM = 128;
public static bool[,] m_bTokenUseState = new bool[MAX_PROCESS_NUM, MAX_TOKEN_NUM];
private static object objWait = new object();
public static int GET_MAX_PROCESS
{
get { return MAX_PROCESS_NUM; }
}
public static void AllClearToken(Connect_Token thisToken)
{
lock (objWait)
{
for (int i = 0; i < MAX_TOKEN_NUM; i++)
m_bTokenUseState[(int)thisToken, i] = false;
}
}
public static bool GetTokenPosState(Connect_Token thisToken, int iPos)
{
bool bValue = false;
if (iPos >= 0 && iPos < MAX_TOKEN_NUM)
bValue = m_bTokenUseState[(int)thisToken, iPos];
return bValue;
}
public static void SetTokenState(Connect_Token thisToken, bool bValue)
{
lock (objWait)
{
for (int i = 0; i < MAX_TOKEN_NUM; i++)
{
if (m_bTokenUseState[(int)thisToken, i] == !bValue)
{
m_bTokenUseState[(int)thisToken, i] = bValue;
break;
}
}
}
}
//사용 불가능 true 가능 false
public static bool GetTokenState(Connect_Token thisToken)
{
bool bUnused = true;
for (int i = 0; i < MAX_TOKEN_NUM; i++)
{
if (m_bTokenUseState[(int)thisToken, i] == false)
{
//사용 가능
bUnused = false;
return bUnused;
}
}
//사용 불가능
bUnused = true;
return bUnused;
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace SystemX.Net.Comm.IIS_FTP
{
public enum eFTPServiceStatus
{
None = 0,
Unused,
Connected,
Disconnected
}
}

View File

@ -0,0 +1,578 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace SystemX.Net.Comm.IIS_FTP
{
public class CtrlFTP : ManagerInfoFTP
{
public CtrlFTP(bool bUseService, IPAddress SetIpAddress, int nSetPort, string strSetUserName, string strSetUserPassword)
: base (bUseService, SetIpAddress, nSetPort, strSetUserName, strSetUserPassword)
{
/*
"14.33.116.123", "2121"
"ALISFTP", "Kefico!@34"
*/
if (Connect())
FTPConnState = true;
else
FTPConnState = false;
string strGetLastCommandState = LastestCommandDebugInformation();
}
public override string GetLastestCommandStatusDescriptionText()
{
return LastestCommandStatusDescription;
}
public override FtpStatusCode GetLastestCommandStatusCodeText()
{
return LastestCommandStatusCode;
}
public override string GetLastestExceptionText()
{
return LastestCommandException.Message;
}
public override Exception GetLastestException()
{
return LastestCommandException;
}
public bool Connect()
{
LastestCommandException = null;
bool bCommandResult = true;
string url = string.Format(@"FTP://{0}:{1}/", UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.ListDirectory;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
StringBuilder sb = new StringBuilder();
FtpWebResponse wr = null;
try
{
using (wr = (FtpWebResponse)fwr.GetResponse())
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
}
}
catch(Exception FtpException)
{
bCommandResult = false;
LastestCommandException = FtpException;
}
finally
{
if(wr != null)
{
wr.Close();
wr = null;
}
}
return bCommandResult;
}
private List<string> CheckList(StringBuilder sb, bool bFolderCheck = false, string strFolderPath = "")
{
List<string> lstInfo = new List<string>();
string[] directorys = sb.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string strList in directorys)
{
string[] strGetItems = new string[4];
int[] nSplitPos = new int[3];
string strCopyText = strList;
for (int n = 0; n < 3; n++)
{
int nPos = strCopyText.IndexOf(' ');
int nOriginPosition = nPos;
int nCnt = 0;
while (strCopyText[nPos] == ' ')
{
nPos++;
nCnt++;
}
string strTempText = strCopyText.Substring(0, nOriginPosition);
strCopyText = strCopyText.Remove(0, nOriginPosition + nCnt);
strGetItems[n] = strTempText;
}
strGetItems[3] = strCopyText;
//string[] strGetItems = strList.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (strGetItems.Length != 4)
continue;
if (bFolderCheck)
{
if (strGetItems[2] != "<DIR>")
continue;
if (strFolderPath.Length == 0)
lstInfo.Add(strGetItems[3]);
else
{
if (strFolderPath.CompareTo(strGetItems[3]) == 0)
{
lstInfo.Add(strGetItems[3]);
break;
}
}
}
else
{
if (strGetItems[2] == "<DIR>")
continue;
DateTime dt = new DateTime();
if (DateTime.TryParse(strGetItems[0] + " " + strGetItems[1], CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.None, out dt))
{
TimeSpan ts = DateTime.Now - dt;
if (ts.TotalSeconds >= ManagerInfoFTP.dDiffScanCheckFileTime)
lstInfo.Add(strGetItems[3]);
// TODO : FTP Download file list chekc limit 2048
if (lstInfo.Count >= 2048)
break;
}
else //Parsing failed!
continue;
}
}
return lstInfo;
}
public List<string> PositionRootCheckList(bool bFolderCheck = false, string strFolderPath = "")
{
LastestCommandException = null;
bool bCommandResult = true;
List<string> lstInfo = new List<string>();
string url = string.Format(@"FTP://{0}:{1}/", UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
StringBuilder sb = new StringBuilder();
FtpWebResponse wr = null;
try
{
using (wr = (FtpWebResponse)fwr.GetResponse())
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
StreamReader streamReader = new StreamReader(wr.GetResponseStream(), Encoding.Default);
sb.Append(streamReader.ReadToEnd());
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
if (bCommandResult)
lstInfo = CheckList(sb, bFolderCheck, strFolderPath);
return lstInfo;
}
public List<string> PositionSubCheckList(string strSubPath, bool bFolderCheck = false, string strFolderPath = "")
{
LastestCommandException = null;
bool bCommandResult = true;
List<string> lstInfo = new List<string>();
string url = string.Format(@"FTP://{0}:{1}/" + strSubPath + @"/", UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
StringBuilder sb = new StringBuilder();
FtpWebResponse wr = null;
try
{
using (wr = (FtpWebResponse)fwr.GetResponse())
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
StreamReader streamReader = new StreamReader(wr.GetResponseStream(), Encoding.Default);
sb.Append(streamReader.ReadToEnd());
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
if (bCommandResult)
lstInfo = CheckList(sb, bFolderCheck, strFolderPath);
return lstInfo;
}
public bool MakeDirectory(string strDirectoryPath)
{
LastestCommandException = null;
bool bCommandResult = true;
string url = string.Format(@"FTP://{0}:{1}/" + strDirectoryPath + @"/", UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = null;
FtpWebResponse wr = null;
try
{
fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.MakeDirectory;
fwr.Credentials = new NetworkCredential("ALISFTP", "Kefico!@34");
StringBuilder sb = new StringBuilder();
using (wr = (FtpWebResponse)fwr.GetResponse())
{
// FTP 결과 스트림
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
if (LastestCommandStatusCode != System.Net.FtpStatusCode.PathnameCreated)
bCommandResult = false;
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
return bCommandResult;
}
public bool FileExist(string strFileName)
{
LastestCommandException = null;
bool bCommandResult = true;
string url = string.Format(@"FTP://{0}:{1}/" + strFileName, UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = null;
FtpWebResponse wr = null;
try
{
fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.GetFileSize;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
StringBuilder sb = new StringBuilder();
using (wr = (FtpWebResponse)fwr.GetResponse())
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
if (LastestCommandStatusCode == System.Net.FtpStatusCode.ActionNotTakenFileUnavailable)
bCommandResult = false;
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
return bCommandResult;
}
public bool DeleteFile(string strFileName)
{
LastestCommandException = null;
bool bCommandResult = true;
string url = string.Format(@"FTP://{0}:{1}/" + strFileName, UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
FtpWebRequest fwr = null;
FtpWebResponse wr = null;
try
{
fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
//fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.DeleteFile;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
StringBuilder sb = new StringBuilder();
using (wr = (FtpWebResponse)fwr.GetResponse())
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
if (LastestCommandStatusCode != System.Net.FtpStatusCode.FileActionOK)
bCommandResult = false;
else
{
if (LastestCommandStatusDescription.IndexOf("DELE command successful") < 0)
bCommandResult = false;
}
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
return bCommandResult;
}
public bool FileUpload(string strFilePos)
{
string strFileName = Path.GetFileName(strFilePos);
string url = string.Format(@"FTP://{0}:{1}/" + strFileName, UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
LastestCommandException = null;
bool bCommandResult = true;
FtpWebRequest fwr = null;
FtpWebResponse wr = null;
try
{
fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.UploadFile;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
// 입력파일을 바이트 배열로 읽음
byte[] ucReadData;
using (FileStream reader = new FileStream(strFilePos, FileMode.Open, FileAccess.Read))
{
ucReadData = new byte[reader.Length];
reader.Read(ucReadData, 0, (int)reader.Length);
}
// RequestStream에 데이타를 쓴다
fwr.ContentLength = ucReadData.Length;
using (Stream reqStream = fwr.GetRequestStream())
{
reqStream.Write(ucReadData, 0, ucReadData.Length);
}
// FTP Upload 실행
using (wr = (FtpWebResponse)fwr.GetResponse())
{
// FTP 결과 상태 출력
//Console.WriteLine("Upload: {0}", wr.StatusDescription);
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
if (LastestCommandStatusDescription.IndexOf("Transfer complete") >= 0)
bCommandResult = true;
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
return bCommandResult;
}
public async Task<string> FileDownload(string strDownloadFileName, string strCreateFilePath)
{
string url = string.Format(@"FTP://{0}:{1}/" + strDownloadFileName, UseInfo.InfoIPAddress.ToString(), UseInfo.InfoPort.ToString());
LastestCommandException = null;
bool bCommandResult = true;
FtpWebRequest fwr = null;
FtpWebResponse wr = null;
try
{
fwr = (FtpWebRequest)WebRequest.Create(url);
fwr.KeepAlive = false;
fwr.UseBinary = true;
fwr.UsePassive = true;
fwr.Method = WebRequestMethods.Ftp.DownloadFile;
fwr.Credentials = new NetworkCredential(UseInfo.InfoUseUserAccount, UseInfo.InfoUseUserPassword);
// FTP Request 결과를 가져온다.
using (wr = (FtpWebResponse)fwr.GetResponseAsync().ConfigureAwait(false).GetAwaiter().GetResult())
{
// FTP 결과 스트림
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
Stopwatch stWaitTime = new Stopwatch();
stWaitTime.Start();
while (true)
{
LastestCommandStatusDescription = wr.StatusDescription;
LastestCommandStatusCode = wr.StatusCode;
if (stWaitTime.ElapsedMilliseconds >= 10000)
throw new Exception("Can't FtpStatusCode.DataAlreadyOpen|FtpStatusCode.ClosingData");
if (LastestCommandStatusCode == System.Net.FtpStatusCode.DataAlreadyOpen ||
LastestCommandStatusCode == System.Net.FtpStatusCode.ClosingData)
break;
await Task.Delay(0);
}
Stream stream = wr.GetResponseStream();
FileStream fileStream = new FileStream(strCreateFilePath + strDownloadFileName, FileMode.Create);
byte[] ucBuffer = new byte[4096];
int nBytesRead;
while (true)
{
nBytesRead = stream.Read(ucBuffer, 0, ucBuffer.Length);
if (nBytesRead == 0)
break;
fileStream.Write(ucBuffer, 0, nBytesRead);
}
fileStream.Close();
}
}
catch (Exception FtpException)
{
LastestCommandException = FtpException;
bCommandResult = false;
}
finally
{
if (wr != null)
{
wr.Close();
wr = null;
}
}
if (bCommandResult)
return strCreateFilePath + strDownloadFileName;
else
return string.Empty;
}
}
}

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace SystemX.Net.Comm.IIS_FTP
{
public class ManagerInfoFTP
{
protected static double dDiffScanCheckFileTime = 60.0;
public sealed class ConnectFTPInformation
{
public bool UseFTPService { set; get; }
public IPAddress InfoIPAddress { set; get; }
public int InfoPort { set; get; }
public string InfoUseUserAccount { set; get; }
public string InfoUseUserPassword { set; get; }
}
protected ConnectFTPInformation UseInfo { set; get; }
protected string LastestCommandStatusDescription { set; get; }
protected FtpStatusCode LastestCommandStatusCode { set; get; }
protected Exception LastestCommandException { set; get; }
public virtual string GetLastestCommandStatusDescriptionText()
{
return string.Empty;
}
public virtual FtpStatusCode GetLastestCommandStatusCodeText()
{
return FtpStatusCode.Undefined;
}
public virtual string GetLastestExceptionText()
{
return string.Empty;
}
public virtual Exception GetLastestException()
{
return null;
}
public string LastestCommandDebugInformation()
{
string strMakeMessage = string.Format("{0}@{1}", LastestCommandStatusDescription, LastestCommandStatusCode.ToString());
if (LastestCommandException != null)
strMakeMessage += "@" + LastestCommandException.Message;
return strMakeMessage;
}
public ManagerInfoFTP(bool bUseService, IPAddress SetIpAddress, int nSetPort, string strSetUserName, string strSetUserPassword)
{
UseInfo = new ConnectFTPInformation();
UseInfo.UseFTPService = bUseService;
UseInfo.InfoIPAddress = SetIpAddress;
UseInfo.InfoPort = nSetPort;
UseInfo.InfoUseUserAccount = strSetUserName;
UseInfo.InfoUseUserPassword = strSetUserPassword;
}
public bool FTPConnState { set; get; }
}
}