📄 xynetsocket.cs
字号:
//nPos = 0;
//nStart = DateTime.Now.Ticks;
//while(nPos<nSize)
//{
// if(sock.Available>0)
// {
// nPos += sock.Receive(pData, nPos, Math.Min(sock.Available, (nSize-nPos)), SocketFlags.None);
// }
// else Thread.Sleep(m_nServerPause);
// if(nPos<nSize&&((DateTime.Now.Ticks-nStart)/10000)>m_nReadTimeout*1000) throw new Exception("Timeout while receiving incoming data");
//}
Monitor.Enter(this);
m_listSockets.Add(sock);
Monitor.Exit(this);
//Everything will be handled as binary, no need to check on what type it is
// if((pHeader[0]&0x0000000F)==1)
// {
// if(m_delegateBinaryInputHandler!=null)
// {
// m_threadPool.InsertWorkItem("Handle Binary Input", new BinaryInputHandlerDelegate(m_delegateBinaryInputHandler), new Object[3] {ipe.Address.ToString(), ipe.Port, pData}, false);
// }
// else throw new Exception("No binary input handler");
// }
// else if((pHeader[0]&0x0000000F)==0)
// {
// if(m_delegateStringInputHandler!=null)
// {
// m_threadPool.InsertWorkItem("Handle String Input", new StringInputHandlerDelegate(m_delegateStringInputHandler), new Object[3] {ipe.Address.ToString(), ipe.Port, XYNetCommon.BinaryToString(pData)}, false);
// }
// else throw new Exception("No string input handler");
// }
// else throw new Exception("Invalid string data size");
//}
if(m_delegateBinaryInputHandler!=null)
{
// string Printer = "";
// for (int x = 0; x < pData.Length; x++)
// {
// Printer += (Convert.ToString(pData[x], 16)).PadLeft(2, '0');
// }
// Console.WriteLine(sock.RemoteEndPoint.ToString() + " " + Printer);
m_threadPool.InsertWorkItem("Handle Binary Input", new BinaryInputHandlerDelegate(m_delegateBinaryInputHandler), new Object[3] {ipe.Address.ToString(), ipe.Port, pData}, false);
}
else throw new Exception("No binary input handler");
}
catch(Exception oBug)
{
Monitor.Enter(this);
try
{
if(m_delegateExceptionHandler!=null)
{
m_delegateExceptionHandler.DynamicInvoke(new Object[2]{oBug, sock});
}
else
{
Monitor.Enter(this);
m_exception = oBug;
Monitor.Exit(this);
}
}
catch (Exception)
{
}
m_htSockets.Remove(ipe.Address.ToString() + ":" + ipe.Port.ToString());
try
{
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
catch(Exception) {}
finally
{
Monitor.Exit(this);
}
}
}
public bool SendRawData(String sRemoteAddress, int nRemotePort, Byte[] pData)
{
if(sRemoteAddress==null||pData==null) return false;
Socket sock = null;
try
{
Monitor.Enter(this);
sock = (Socket)(m_htSockets[sRemoteAddress+":"+nRemotePort.ToString()]);
if(sock==null) throw new Exception("No client connection at the given address and port");
if(m_listSockets.Contains(sock)==false)
{
sock = null;
throw new Exception("Client socket in use");
}
return sock.Send(pData)==pData.Length;
}
catch(Exception oBug)
{
try
{
if(sock!=null)
{
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
}
catch(Exception) {}
if(m_delegateExceptionHandler!=null)
{
m_threadPool.InsertWorkItem("Handle Exception", m_delegateExceptionHandler, new Object[2]{oBug, sock}, false);
}
else m_exception = oBug;
return false;
}
finally { Monitor.Exit(this); }
}
public bool SendBinaryData(String sRemoteAddress, int nRemotePort, Byte[] pData)
{
Byte[] pData2 = new Byte[pData.Length+4];
pData2[0] = (Byte)(1+(pData.Length/16777216)*16);
pData2[1] = (Byte)(pData.Length%256);
pData2[2] = (Byte)((pData.Length%65536)/256);
pData2[3] = (Byte)((pData.Length/65536)%256);
pData.CopyTo(pData2,4);
return SendRawData(sRemoteAddress, nRemotePort, pData2);
}
public bool SendStringData(String sRemoteAddress, int nRemotePort, String sData)
{
Byte[] pData = new Byte[sData.Length*2+4];
pData[0] = (Byte)(((2*sData.Length)/16777216)*16);
pData[1] = (Byte)((2*sData.Length)%256);
pData[2] = (Byte)(((2*sData.Length)%65536)/256);
pData[3] = (Byte)(((2*sData.Length)/65536)%256);
XYNetCommon.StringToBinary(sData).CopyTo(pData, 4);
return SendRawData(sRemoteAddress, nRemotePort, pData);
}
public int GetThreadCount()
{
int nCount = m_threadPool.GetThreadCount()-2;
return nCount>0?nCount:0;
}
public int GetClientCount()
{
Monitor.Enter(this);
int nCount = m_htSockets.Count;
Monitor.Exit(this);
return nCount;
}
}
public class XYNetClient
{
private const int m_nClientPause = 50;
private String m_sRemoteAddress = "";
private int m_nRemotePort = 0;
private int m_nMaxDataSize = 4*1024*1024;
private int m_nReadTimeout = 30;
private Exception m_exception = null;
private Socket m_socketClient = null;
public XYNetClient(String sRemoteAddress, int nRemotePort)
{
if(sRemoteAddress!=null) m_sRemoteAddress = sRemoteAddress;
if(nRemotePort>0) m_nRemotePort = nRemotePort;
}
~XYNetClient()
{
Reset();
}
public Exception GetLastException()
{
Monitor.Enter(this);
Exception exp = m_exception;
Monitor.Exit(this);
return exp;
}
public void SetMaxDataSize(int nMaxDataSize)
{
if(nMaxDataSize>=1024) m_nMaxDataSize = nMaxDataSize;
}
protected Socket GetSocket()
{
Monitor.Enter(this);
Socket sock = m_socketClient;
Monitor.Exit(this);
return sock;
}
public virtual bool Connect()
{
try
{
Monitor.Enter(this);
XYNetCommon.SetSocketPermission();
Reset();
m_socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint myEnd = null;
try
{
myEnd = (m_sRemoteAddress=="")?(new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], m_nRemotePort)):(new IPEndPoint(IPAddress.Parse(m_sRemoteAddress), m_nRemotePort));
}
catch(Exception) {}
if(myEnd==null)
{
myEnd = new IPEndPoint(Dns.GetHostEntry(m_sRemoteAddress).AddressList[0], m_nRemotePort);
}
m_socketClient.Connect(myEnd);
return true;
}
catch(Exception oBug)
{
m_exception = oBug;
try
{
m_socketClient.Shutdown(SocketShutdown.Both);
m_socketClient.Close();
}
catch(Exception) {}
return false;
}
finally { Monitor.Exit(this); }
}
private bool SendRawData(Byte[] pData)
{
try
{
Monitor.Enter(this);
return m_socketClient.Send(pData)==pData.Length;
}
catch(Exception oBug)
{
Connect();
m_exception = oBug;
return false;
}
finally { Monitor.Exit(this); }
}
public bool SendBinaryData(Byte[] pData)
{
Byte[] pData2 = new Byte[pData.Length+4];
pData2[0] = (Byte)(1+(pData.Length/16777216)*16);
pData2[1] = (Byte)(pData.Length%256);
pData2[2] = (Byte)((pData.Length%65536)/256);
pData2[3] = (Byte)((pData.Length/65536)%256);
pData.CopyTo(pData2,4);
return SendRawData(pData2);
}
public bool SendStringData(String sData)
{
Byte[] pData = new Byte[sData.Length*2+4];
pData[0] = (Byte)(((2*sData.Length)/16777216)*16);
pData[1] = (Byte)((2*sData.Length)%256);
pData[2] = (Byte)(((2*sData.Length)%65536)/256);
pData[3] = (Byte)(((2*sData.Length)/65536)%256);
XYNetCommon.StringToBinary(sData).CopyTo(pData, 4);
return SendRawData(pData);
}
public void SetReadTimeout(int nReadTimeout)
{
Monitor.Enter(this);
if(nReadTimeout>=5&&nReadTimeout<=1200) m_nReadTimeout = nReadTimeout;
Monitor.Exit(this);
}
public Object[] ReceiveData()
{
try
{
Monitor.Enter(this);
m_socketClient.Blocking = false;
long nStart = DateTime.Now.Ticks;
int nRead = 0;
int nTotal = 4;
Byte[] pData = new Byte[4];
Byte[] pHeader = null;
while(true)
{
try
{
Thread.Sleep(m_nClientPause);
if(m_socketClient.Available>0)
{
nRead += m_socketClient.Receive(pData, nRead, nTotal-nRead, SocketFlags.None);
if((pData[0]&0x0000000F)==2) nRead = 0;
}
}
catch(Exception) {}
if(pHeader==null&&nRead==4)
{
nTotal = pData[1] + pData[2]*256 + pData[3]*65536+(pData[0]/16)*16777216;
if((pData[0]&0x0000000F)>1) throw new Exception("Invalid input data type byte");
if(nTotal>m_nMaxDataSize) throw new Exception("Data size too large");
pHeader = pData;
nRead = 0;
pData = new Byte[nTotal];
}
if(pHeader!=null&&nRead==nTotal) break;
if(((DateTime.Now.Ticks-nStart)/10000)>m_nReadTimeout*1000) throw new Exception("Timeout while receiving incoming data");
}
if((pHeader[0]&0x0000000F)==1)
{
return new Object[2] { pData, null };
}
else
{
if(pData.Length%2!=0) throw new Exception("Invalid string data size");
return new Object[2] { null, XYNetCommon.BinaryToString(pData) };
}
}
catch(Exception oBug)
{
Connect();
m_exception = oBug;
return null;
}
finally
{
m_socketClient.Blocking = true;
Monitor.Exit(this);
}
}
public void Reset()
{
try
{
Monitor.Enter(this);
if(m_socketClient!=null)
{
m_socketClient.Send(new Byte[4]{255, 0, 0, 0}, SocketFlags.None);
m_socketClient.Shutdown(SocketShutdown.Both);
m_socketClient.Close();
}
}
catch(Exception) {}
finally
{
m_socketClient = null;
Monitor.Exit(this);
}
}
}
public class XYNetCommon
{
public static SocketPermission m_permissionSocket = null;
private static bool m_bPermissionSet = false;
public static void SetSocketPermission()
{
lock(typeof(XYNetCommon))
{
if(m_bPermissionSet==false)
{
if(m_permissionSocket!=null)
{
m_permissionSocket.Demand();
}
m_bPermissionSet = true;
}
}
}
public static String BinaryToString(Byte[] pData)
{
if((pData.Length%2)!=0) throw new Exception("Invalid string data size");
Char[] pChar = new Char[pData.Length/2];
for(int i=0;i<pChar.Length;i++)
{
pChar[i] = (Char)(pData[2*i] + pData[2*i+1]*256);
}
return new String(pChar);
}
public static Byte[] StringToBinary(String sData)
{
Byte[] pData = new Byte[sData.Length*2];
for(int i=0;i<sData.Length;i++)
{
pData[2*i] = (Byte)(sData[i]%256);
pData[2*i+1] = (Byte)(sData[i]/256);
}
return pData;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -