/// <summary> /// 停止服务器 /// </summary> protected override void OnStop() { base.OnStop(); //关闭心跳检查功能 lock (Sessions) { TSession[] array = Sessions.ToArray(); foreach (TSession session in array) { CloseSession(session); } Sessions.Clear(); } try { Socket.Close(); } catch (ObjectDisposedException) { //服务器套接字已经关闭 } NetDebuger.PrintDebugMessage(this.GetType().Name + " Stop, clear resource success"); }
/// <summary> /// 获得虚拟路径 /// </summary> /// <param name="localPath">本地路径</param> /// <returns>返回相对路径,失败返回NULL</returns> internal string MapLocalPathToVirtualPath(string localDir) { if (!localDir.EndsWith(localPathSpliter.ToString())) { localDir += localPathSpliter.ToString(); } if (!HomeDir.EndsWith(localPathSpliter.ToString())) { HomeDir += localPathSpliter.ToString(); } if (localDir == HomeDir) { return(Root); } else { //Unix上的文件名需要大小写匹配 if (localDir.IndexOf(HomeDir) == -1) { NetDebuger.PrintErrorMessage(this, "MAP LOCAL DIR:" + localDir + " TO HOME DIR:" + HomeDir + " FAIL"); return(Root); } else { localDir = localDir.Replace(HomeDir, Root); //把本地路径的分隔符号,替换为虚拟路径的分隔符号 return(localDir.Replace(new string(localPathSpliter, 1), new string(virtualPathSpliter, 1)). Replace(new string(virtualPathSpliter, 2), new string(virtualPathSpliter, 1))); } } }
private void StartUpFtpServer(string HostIP) { try { m_ftpServer.Stop(); ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'"); ManagementObjectCollection nics = query.Get(); foreach (ManagementObject nic in nics) { { if (getIpBaseNum((nic["IPSubnet"] as String[])[0], (nic["IPAddress"] as String[])[0]) == getIpBaseNum((nic["IPSubnet"] as String[])[0], HostIP)) { m_ftpServer.PasvIPSetting = (nic["IPAddress"] as String[])[0]; break; } else { m_ftpServer.PasvIPSetting = null; } } } m_ftpServer.Start(); //Console.WriteLine("Press enter to exit..."); //Console.ReadLine(); //m_ftpServer.Stop(); } catch (System.Exception e) { NetDebuger.PrintErrorMessage("FATAL ERROR:" + e.Message); } }
private static void OnDbgGUI_ProfilerControl() { if (GUILayout.Button("Clear Profiler Cache")) { NetDebuger.ClearSample(); m_dbgFileName = null; } if (string.IsNullOrEmpty(m_dbgFileName)) { m_dbgFileName = GetDefaultFileName(); } GUILayout.Label("Input Profiler FileName:"); m_dbgFileName = GUILayout.TextField(m_dbgFileName); if (GUILayout.Button("Save Profiler File")) { NetDebugFile file = new NetDebugFile(); file.Content.profiler_samples.AddRange(NetDebuger.SampleList); file.Save(NetDebuger.DbgFileDir, m_dbgFileName); NetDebuger.ClearSample(); m_dbgFileName = null; CheckFileList(); } }
protected override void OnConnectServer() { //Send handshake message block to build secure connection like SSL base.Send(new MessageBlock(MessageBlockType.Handshake, (int)HandshakeType.ClientHello)); Session.Handshake = HandshakeType.ClientHello; NetDebuger.PrintDebugMessage(Session, "SEND ClientHello"); }
/// <summary> /// 通讯错误事件 /// </summary> /// <param name="session"></param> /// <param name="e"></param> internal protected virtual void ReportError(TSession session, Exception e) { if (e is SocketException) { SocketException se = e as SocketException; string msg = string.Format("SocketException Code:{0}, Native Code:{1}", se.ErrorCode, se.NativeErrorCode); NetDebuger.PrintErrorMessage(session, msg); } NetDebuger.PrintErrorMessage(session, e.ToString()); }
/// <summary> /// 检查Session是否还在活动 /// </summary> /// <param name="timeOut">超时时间(ms)</param> /// <returns>正在活动返回true,否则返回false</returns> public virtual bool IsActive(int timeOut) { NetDebuger.PrintDebugMessage(this, string.Format("TimeOut:{0}-Period:{1}", timeOut, TimeCounter.Milliseconds)); if (timeOut < TimeCounter.Milliseconds) { return(false); } return(true); }
public void DoReceiveInThread(byte[] buffer, int size) { if (NetDebuger.IsPacketLoss()) { return; } byte[] dst = new byte[size]; Buffer.BlockCopy(buffer, 0, dst, 0, size); m_RecvQueue.Push(dst); }
public override bool IsActive(int timeOut) { NetDebuger.PrintDebugMessage(this, "STATE:" + Statue.ToString()); //会话超时,而且当前状态或者未登陆 if (!base.IsActive(timeOut) && (Statue == FtpSessionStatue.Wait || Statue == FtpSessionStatue.NotLogin)) { return(false); } return(true); }
/// <summary> /// 异步Socket中的接收新连接回调函数 /// </summary> /// <param name="parameter"></param> private void AcceptCallback(IAsyncResult parameter) { TSession session = default(TSession); try { //创建新连接 session = CreateSession(socket.EndAccept(parameter)); if (!Full) { lock (Sessions) { Sessions.Add(session); } //调用客户端生成函数,检查是否为合格的客户端 if (!OnCreateSession(session)) { session.Close(); return; } //开始注册客户端数据接收事件 session.OnReceivedData += new EventHandler <DataBlockArgs>(SessionReceivedData); //开始接收客户端数据 WaitForData(session); NetDebuger.PrintDebugMessage(session, "Create"); NetDebuger.PrintDebugMessage(session, string.Format("Add:{0}/{1}", SessionsCount, Capacity)); } else { OnServerFull(session); NetDebuger.PrintDebugMessage(session, "Server full"); session.Close(); } } catch (ObjectDisposedException) { //监听的Socket已经关闭 } catch (SocketException e) { HandleSocketException(session, e); CloseSession(session); //接收数据发送错误,需要关闭该Socket } finally { WaitForClient();//继续接收客户端连接 } }
void SessionOnReceivedMessageBlock(object sender, MessageBlockArgs e) { if (e.MessageBlock.Type == MessageBlockType.HeartBeat && EnableCheckHeartBeat) { Session.TimeCounter.Reset(); //Refresh the heart Beat timer NetDebuger.PrintDebugMessage(Session, "Recv server heart Beat"); } else { OnReceivedMessageBlock(e.MessageBlock); } }
//private void private void SafeSend(DataBlock target) { lock (sendQueue.SyncRoot) { sendQueue.Enqueue(target);//添加到发送列表 NetDebuger.PrintDebugMessage("Send Queue Length:" + sendQueue.Count.ToString()); if (sendQueue.Count == 1) { AtomSend(target); } } }
/// <summary> /// 启动服务器,监听客户端连接 /// </summary> protected override void OnStart() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep = new IPEndPoint(IPAddress.Any, Port); socket.Bind(iep); socket.Listen(100); WaitForClient(); //等待客户端连接 NetDebuger.PrintDebugMessage( string.Format("{0} is running, listen port:{1} and capacity:{2}", this.GetType().Name, Port, Capacity)); base.OnStart(); //启动心跳检查功能 }
//--------------------------------------------- private void HandleKcpSend(byte[] buff, int size) { if (NetDebuger.EnableWeakNet) { NetDebuger.WeakNetSimulate(this, buff, size, HandleKcpSend_Hook); } else { if (m_Socket != null) { m_Socket.SendTo(buff, 0, size, SocketFlags.None, m_RemotePoint); } } }
public void Dispose() { m_Socket = null; NetDebuger.WeakNetCancel(this); if (m_Kcp != null) { m_Kcp.Dispose(); m_Kcp = null; } m_Listener = null; }
protected virtual void StartHeartBeat() { /*如果EnableCheckHeartBeat=true,会启动心跳检查,这样就不能调用基类的OnStart()函数 * 服务器设定一个心跳超时时间,客户端检查超时的时间应该与此一致。客户端程序会在该时间 * 的二分之一时间内,发送一个心跳包,服务器会返回一个心跳包,这样客户端就能够知道服务器段能够正确的响应。 */ if (EnableCheckHeartBeat) { checkTimer = new Timer(new TimerCallback(CheckHeartBeatCallBack), null, HeartBeatPeriod / 2, HeartBeatPeriod / 2); NetDebuger.PrintDebugMessage("Start heart Beat checker, Period:" + HeartBeatPeriod + "(ms)"); Session.TimeCounter.Start(); } }
/// <summary> /// 关闭会话,把会话从服务器中移除 /// </summary> /// <param name="session">需要关闭的Session</param> protected virtual void CloseSession(TSession session) { lock (Sessions) { if (Sessions.Contains(session)) { Sessions.Remove(session); NetDebuger.PrintDebugMessage(session, "Close"); NetDebuger.PrintDebugMessage(session, string.Format("Remove:{0}/{1}", SessionsCount, Capacity)); OnCloseSession(session); //关闭前调用 session.Close(); } } }
private void SendFile(object arg) { FtpCommand cmd = arg as FtpCommand; if (cmd.Parameters.Count == 0) { throw new SyntaxException(); } CheckDataConnExist(); try { Statue = FtpSessionStatue.Download; bool isFile; string localPath = GetLocalPath(cmd.Parameters[0], FtpOption.Download, out isFile); if (isFile) { Response("150 Opening BINARY mode data connection for file transfer."); if (dataConn.SendFile(localPath, restartPos)) { Response("226 Transfer complete."); } else { Response("426 Connection closed; transfer aborted."); } } else { throw new FileNotFoundException(cmd.Parameters[0]); } } catch (FtpException) { throw; } catch (Exception e) { NetDebuger.PrintErrorMessage(this, e.ToString()); throw new InternalException(e.Message); } finally { CloseDataConn(); Statue = FtpSessionStatue.Wait; } }
protected override void CheckHeartBeatCallBack(object o) { //If client is on line, go on send heart Beat singal if (IsConnected) { base.CheckHeartBeatCallBack(o); } if (IsConnected)//如果没有掉线,继续发送心跳信号 { MessageBlock heartBeatMB = new MessageBlock(MessageBlockType.HeartBeat); Send(heartBeatMB); NetDebuger.PrintDebugMessage(Session, "Send Heart Beat"); } }
/// <summary> /// 检查是否是有效IP /// </summary> /// <param name="newSession"></param> /// <returns>如果客户端的IP被限制返回false,否则返回true</returns> protected virtual bool CheckClientIP(FtpSession newSession) { IPEndPoint remote = newSession.Socket.RemoteEndPoint as IPEndPoint; string remoteIP = remote.Address.ToString(); foreach (string ip in IPFilter) { if (remoteIP == ip) { NetDebuger.PrintDebugMessage(newSession, "Server rejected the client:" + remoteIP); return(false); } } NetDebuger.PrintDebugMessage(newSession, "Server accepted the client:" + remoteIP); return(true); }
void SessionOnReceivedMessageBlock(object sender, MessageBlockArgs e) { if (EnableCheckHeartBeat) { if (e.MessageBlock.Type == MessageBlockType.HeartBeat) { TSession session = (TSession)sender; //Todo:多线程安全 session.TimeCounter.Reset(); //定时器开始新的计时 Send(session, e.MessageBlock); NetDebuger.PrintDebugMessage(session, "Heartbeat"); return; } } OnReceivedMessageBlock((TSession)sender, e.MessageBlock); }
private void STOR(FtpCommand cmd) { CheckLogin(); if (cmd.Parameters.Count == 0) { throw new SyntaxException(); } CheckDataConnExist(); restartPos = 0; try { Statue = FtpSessionStatue.Upload; bool isFile; string localPath = GetLocalPath(cmd.Parameters[0], FtpOption.Upload, out isFile); dataConn.MaxLengthOfUpload = user.MaxUploadFileLength; dataConn.RecvFile = new FileStream(localPath, FileMode.Create); Response("150 Opening BINARY mode data connection for file transfer."); if (dataConn.ReceiveFile(localPath, restartPos)) { Response("226 Transfer complete."); } else { NetDebuger.PrintErrorMessage(this, dataConn.AsyncHelper.Exception.Message); Response("426 Connection closed; transfer aborted."); } } catch (FtpException) { throw; } catch (Exception e) { NetDebuger.PrintErrorMessage(this, e.ToString()); throw new InternalException("store file"); } finally { CloseDataConn(); Statue = FtpSessionStatue.Wait; } }
public int SendTo(byte[] buffer, int size, IPEndPoint remoteEP) { int cnt = 0; if (NetDebuger.IsPacketLoss()) { return(0); } //如果无法使用LocalSocket再使用SystemSocket if (cnt == 0) { cnt = m_SystemSocket.SendTo(buffer, 0, size, SocketFlags.None, remoteEP); } return(cnt); }
/// <summary> /// 分发FTP请求 /// </summary> /// <param name="cmdText"></param> internal void SwitchFtpRequest(string cmdText) { NetDebuger.PrintErrorMessage(this, cmdText); if (string.IsNullOrEmpty(cmdText)) { return; } FtpCommand cmd; int index = cmdText.IndexOf(' '); //把命令和参数部分分开 if (index != -1) { //把命令转成大写 cmd = new FtpCommand(cmdText.Substring(0, index).ToUpper()); cmd.Parameters.Add(cmdText.Substring(index + 1)); } else { //把命令转成大写 cmd = new FtpCommand(cmdText.ToUpper()); } //会话重新开始计时 TimeCounter.Reset(); try { if (!ftpHandlers.ContainsKey(cmd.Command)) { throw new CommandNotImplementedException(); } //分发各个命令 ftpHandlers[cmd.Command].Invoke(cmd); } catch (FtpException e) { Response(e.Message); } catch (Exception e) { NetDebuger.PrintErrorMessage(this, e.ToString()); } }
private void RaiseDropLineEvent() { NetDebuger.PrintDebugMessage("Raise Drop Line Event"); lock (syncSessionObj) { NetDebuger.PrintDebugMessage("Lock drop"); bool temp = IsConnected; if (temp) { Stop(); OnDropLine(); } NetDebuger.PrintDebugMessage("UnLock drop"); } }
protected override void OnStart() { IPAddress[] hostIPAddress = Dns.GetHostAddresses(Host); if (hostIPAddress.Length == 0) { throw new NetException("Get host ddress fail"); } isConnected = false; sendQueue.Clear(); IPEndPoint iep = new IPEndPoint(hostIPAddress[0], Port); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Socket.BeginConnect(iep, ConnectCallBack, null); NetDebuger.PrintDebugMessage(string.Format("Connecting server:{0}:{1}...", hostIPAddress[0].ToString(), port)); }
//------------------------------------------------------------ #region ReceiveFrom和SendTo函数 public int ReceiveFrom(byte[] buffer, int maxsize, ref IPEndPoint remoteEP) { int cnt = 0; EndPoint ip = null; if (!m_EnableBlockOnRecv) { if (m_SystemSocket.Available <= 0) { return(0); } } if (m_AddrFamily == AddressFamily.InterNetwork) { //如果是IPv4环境,则(与Android的处理一样) ip = IPUtils.GetIPEndPointAny(AddressFamily.InterNetwork, 0); cnt = m_SystemSocket.ReceiveFrom(buffer, maxsize, SocketFlags.None, ref ip); if (cnt > 0 && remoteEP != null && !remoteEP.Equals(ip)) { Debuger.LogWarning(LOG_TAG, "ReceiveFrom() 收到一个自来陌生IP:Port(" + ip + ")的数据包!"); return(0); } } else { //如果是IPv6环境,则: ip = remoteEP; cnt = m_SystemSocket.ReceiveFrom(buffer, maxsize, SocketFlags.None, ref ip); } remoteEP = ip as IPEndPoint; if (NetDebuger.IsPacketLoss()) { return(0); } return(cnt); }
/// <summary> /// 心跳检查回调函数 /// </summary> /// <param name="para"></param> protected override void CheckHeartBeatCallBack(object para) { List <TSession> closeSessions = new List <TSession>(); lock (Sessions) { foreach (TSession session in Sessions) { if (!session.IsActive(HeartBeatPeriod)) //todo:是否需要修改到服务器方法 { closeSessions.Add(session); NetDebuger.PrintDebugMessage(session, "Heartbeat is timeout and add it to closing list"); } } } foreach (TSession session in closeSessions) { CloseSession(session); } }
void CreateDataConnection() { //关闭以前的数据连接 CloseDataConn(); //生成新的数据连接 dataConn = new FtpDataConnection(); dataConn.Start(); IPEndPoint localPoint = (IPEndPoint)dataConn.Socket.LocalEndPoint; string ipAddress = ftpServer.PasvIPSetting.Replace(".", ","); StringBuilder reply = new StringBuilder(); reply.Append("227 Entering Passive Mode("); reply.Append(ipAddress); reply.Append(","); reply.Append(localPoint.Port / 256); reply.Append(","); reply.Append(localPoint.Port % 256); reply.Append(")."); Response(reply.ToString()); try { //在规定时间内等待客户端的数据连接 dataConn.Accept(opertionTimeout); } catch (TimeoutException) { CloseDataConn(); NetDebuger.PrintDebugMessage("Timeout wait for data connection"); } catch { CloseDataConn(); NetDebuger.PrintDebugMessage("Interrupted for wait for data connection"); } }
protected override void OnDropLine() { base.OnDropLine(); NetDebuger.PrintDebugMessage("Client is drop line."); }