⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xynetsocket.cs

📁 网络游戏征服的服务端部分完整源码 VC编译 绝少的源码 有兴趣的可以
💻 CS
📖 第 1 页 / 共 2 页
字号:
				//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 + -