/// <summary> /// 清除客户端 /// </summary> /// <param name="userToken"></param> public void CloseClientSocket(SocketUserToken userToken) { if (userToken.ConnectSocket == null) { return; } DelegateState.ReomveTCPStateInfo(userToken); string socketInfo = string.Format(" 删除地址: {0}", userToken.ConnectSocket.RemoteEndPoint); try { userToken.SendUserTokenAll.Clear();//清除设备连接 userToken.ConnectSocket.Shutdown(SocketShutdown.Both); } catch (Exception E) { DelegateState.ServerStateInfo("断开连接 " + socketInfo + " error, message: {1}" + E.Message); } userToken.LoginFlag = false; userToken.ConnectSocket.Close(); userToken.ConnectSocket = null; //释放引用,并清理缓存,包括释放协议对象等资源 serverconfig.semap.Release(); //增加个一信号量 m_asyncSocketUserTokenPool.Push(userToken); AsyncSocketUserList.Remove(userToken); }
/// <summary> /// 异步发送及接收回调函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void IO_Completed(object sender, SocketAsyncEventArgs asyncEventArgs) { SocketUserToken userToken = asyncEventArgs.UserToken as SocketUserToken; userToken.ActiveDateTime = DateTime.Now; try { lock (userToken) { if (asyncEventArgs.LastOperation == SocketAsyncOperation.Receive) { ProcessReceive(asyncEventArgs); } else if (asyncEventArgs.LastOperation == SocketAsyncOperation.Send) { ProcessSend(asyncEventArgs); } else { throw new ArgumentException("最后一次操作完成套接字接收或发送"); } } } catch (Exception ex) { DelegateState.ServerStateInfo("异步发送及接收回调函数: IO_Completed " + userToken.ConnectSocket + " error, message: " + ex.Message); } }
/// <summary> /// 添加新客户 /// </summary> /// <param name="acceptEventArgs"></param> private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) { if (acceptEventArgs.AcceptSocket.RemoteEndPoint == null) { throw new Exception("服务器停止."); } DelegateState.ServerStateInfo(" TCP - 客户端:" + acceptEventArgs.AcceptSocket.RemoteEndPoint + "连接"); DelegateState.ServerConnStateInfo(acceptEventArgs.AcceptSocket.RemoteEndPoint.ToString(), "TCP"); SocketUserToken userToken = m_asyncSocketUserTokenPool.Pop(); m_asyncSocketUserList.Add(userToken); userToken.ConnectSocket = acceptEventArgs.AcceptSocket; userToken.ConnectDateTime = DateTime.Now; try { bool willRaiseEvent = userToken.ConnectSocket.ReceiveAsync(userToken.ReceiveEventArgs);//异步回调函数确定 if (!willRaiseEvent) { lock (userToken) { ProcessReceive(userToken.ReceiveEventArgs); } } } catch (Exception e) { DelegateState.ServerStateInfo("连接端 " + userToken.ConnectSocket + " 错误, 错误信息: " + e.Message); } StartAccept(acceptEventArgs);//递归继续异步监控客户端 }
/// <summary> /// 异步接收请求 /// </summary> /// <param name="socketAsyncEventArgs"></param> private void ProcessReceive(SocketAsyncEventArgs socketAsyncEventArgs) { SocketUserToken userToken = socketAsyncEventArgs.UserToken as SocketUserToken; if (userToken.ConnectSocket == null) { return; } userToken.ActiveDateTime = DateTime.Now; if (userToken.ReceiveEventArgs.BytesTransferred > 0 && userToken.ReceiveEventArgs.SocketError == SocketError.Success) { int offset = userToken.ReceiveEventArgs.Offset; int count = userToken.ReceiveEventArgs.BytesTransferred; if ((userToken.InvokeElement == null) & (userToken.ConnectSocket != null)) // 第一次发送的数据为-初始话是登录模式 还是 信息模式 { BuildingInvokeElement(userToken); // offset = offset + 1; // count = count - 1; } // userToken.InvokeElement = if (userToken.InvokeElement == null) //如果没有解析对象,提示非法连接并关闭连接 { DelegateState.ServerStateInfo("非法连接:" + userToken.ConnectSocket.RemoteEndPoint); CloseClientSocket(userToken); } else { if (count > 0) //处理接收数据 { if (!userToken.InvokeElement.ProcessReceive(userToken.ReceiveEventArgs.Buffer, offset, count)) //处理数据 { //如果处理数据返回失败,则断开连接 CloseClientSocket(userToken); } else { bool willRaiseEvent = userToken.ConnectSocket.ReceiveAsync(userToken.ReceiveEventArgs); //继续异步接收 if (!willRaiseEvent) { ProcessReceive(userToken.ReceiveEventArgs); } } } } } else { DelegateState.ServerStateInfo(string.Format("空数据,断线 {0}", userToken.ConnectSocket.RemoteEndPoint)); CloseClientSocket(userToken); } }
/// <summary> /// 异步监控回调函数 /// </summary> private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) { try { ProcessAccept(e); } catch (Exception ex) { DelegateState.ServerStateInfo("连接异常:" + ex.Message); //DelegateState.ServerStateInfo(ex.StackTrace); } }
/// <summary> /// 启动UDP /// </summary> public void Start() { if (IsStartListening) { return; } semap = new Semaphore(30000, 30000); IsStartListening = true; thread = new Thread(new ThreadStart(StartAccept)); thread.Start(); m_DaemonThread = new DaemonThreadUDP(this); DelegateState.ServerStateInfo("UDP服务器启动..."); }
/// <summary> /// 初始化类,确定是登录或者发送信息 和其它的API /// </summary> /// <param name="userToken"></param> private void BuildingInvokeElement(SocketUserToken userToken) { //获取接收的0个字节-初始化是登录还是信息 byte flag = userToken.ReceiveEventArgs.Buffer[userToken.ReceiveEventArgs.Offset]; if (flag == (byte)ProtocolFlags.Login) { userToken.InvokeElement = new LoginSocketProtocol(this, userToken); } if (userToken.InvokeElement != null) { DelegateState.ServerStateInfo(userToken.ConnectSocket.RemoteEndPoint + "登录初始化"); } }
/// <summary> /// 启动服务器 /// </summary> /// <param name="localEndPoint"></param> public void Start() { if (IsStartListening) { return; } IsStartListening = true; Init(); listenSocket = new Socket(serverconfig.locahostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(serverconfig.locahostEndPoint); listenSocket.Listen(serverconfig.numConnections); DelegateState.ServerStateInfo("TCP服务器启动..."); StartAccept(null); serverconfig.m_daemonThread = new DaemonThread(this);//启动连接超时判断 }
/// <summary> /// 信息组装 /// </summary> /// <param name="protocolText"></param> /// <returns></returns> public bool DecodeProtocolText(string protocolText) { //再次组装前,先清除上一次信息 m_header = ""; m_names.Clear(); m_values.Clear(); int speIndex = protocolText.IndexOf(ProtocolKeys.ReturnWrap); if (speIndex < 0) { return(false); } else { //协议组装 string[] tmpNameValues = protocolText.Split(new string[] { ProtocolKeys.ReturnWrap }, StringSplitOptions.RemoveEmptyEntries); if (tmpNameValues.Length < 2) //每次命令至少包括两行 { return(false); } for (int i = 0; i < tmpNameValues.Length; i++)//解析 { string[] tmpStr = tmpNameValues[i].Split(new string[] { ProtocolKeys.EqualSign }, StringSplitOptions.None); if (tmpStr.Length > 1) //存在等号 { if (tmpStr.Length > 2) //超过两个等号,返回失败 { return(false); } if (tmpStr[0].Equals(ProtocolKeys.Command, StringComparison.CurrentCultureIgnoreCase))//找到命令 { m_command = tmpStr[1]; DelegateState.ServerStateInfo("Command命令:" + m_command); } else { m_names.Add(tmpStr[0].ToLower());//(当多条命令需要一次处理时候,需要) m_values.Add(tmpStr[1]); } } } } return(true); }
//登录 public bool DoLogin() { socketUserToken.ActiveDateTime = DateTime.Now; string userName = ""; string password = ""; if (InDataParser.GetValue(ProtocolKeys.UserName, ref userName) & InDataParser.GetValue(ProtocolKeys.Password, ref password)) { if (password.Equals(HelpCommonLib.ComminClass.MD5Encrypt("admin", 16), StringComparison.CurrentCultureIgnoreCase)) { socketUserToken.UserName = "******"; if (password.Length > 4)//物联网时,区分是设备还是用户 密码大于4的是用户 { socketUserToken.isDevice = false; SocketUserSearchHorse(); DelegateState.ServerStateInfo(socketUserToken.ConnectSocket.RemoteEndPoint.ToString() + "用户登录成功"); DelegateState.AddTCPuserStateInfo(socketUserToken); } else { socketUserToken.isDevice = true; m_asyncSocketServer.AsyncSocketDeviceList.Add(socketUserToken); DelegateState.ServerStateInfo(socketUserToken.ConnectSocket.RemoteEndPoint.ToString() + "设备连接成功"); DelegateState.AddTCPdeviceStateInfo(socketUserToken); } socketUserToken.LoginFlag = true; socketUserToken.ReceiveBuffer.Clear(); socketUserToken.SendBuffer.ClearPacket(); OutDataParser.Clear(); OutDataParser.AddResponse(); OutDataParser.AddCommand(ProtocolCodes.Success.ToString());//添加返回信息 插入-1 return(true); } socketUserToken.LoginFlag = false; return(false); } socketUserToken.LoginFlag = false; return(false); }
public void DaemonThreadStart() { while (m_thread.IsAlive) { SocketUserUDP[] userUDPArray = new SocketUserUDP[m_asyncudpServer.DeviceInfoList.Count]; m_asyncudpServer.DeviceInfoList.CopyTo(userUDPArray); for (int i = 0; i < userUDPArray.Length; i++) { if (!m_thread.IsAlive) { break; } try { if ((DateTime.Now - userUDPArray[i].ActiveDateTime).Milliseconds > m_asyncudpServer.socketTimeoutMs) { lock (userUDPArray[i]) { m_asyncudpServer.DeviceInfoList.Remove(userUDPArray[i]); } } for (int x = 0; x < 60 * 1000 / 10; x++) //每十分钟检测一次 { if (!m_thread.IsAlive) { break; } Thread.Sleep(100); } TeartbeatCount++; DelegateState.ServerStateInfo("UDP:" + TeartbeatCount + "心跳检测"); } catch (Exception ex) { DelegateState.ServerStateInfo("Error:类[DaemonThreadUDP]" + ex.Message); } } } }
public void DaemonThreadStart() { while (m_thread.IsAlive) { SocketUserToken[] userTokenArray = null; m_asyncSocketServer.AsyncSocketUserList.CopyList(ref userTokenArray); for (int i = 0; i < userTokenArray.Length; i++) { if (!m_thread.IsAlive) { break; } try { if ((DateTime.Now - userTokenArray[i].ActiveDateTime).Milliseconds > m_asyncSocketServer.serverconfig.socketTimeoutMs) { lock (userTokenArray[i]) { m_asyncSocketServer.CloseClientSocket(userTokenArray[i]); } } for (int x = 0; x < 60 * 1000 / 10; x++) //每十分钟检测一次 { if (!m_thread.IsAlive) { break; } Thread.Sleep(100); } TeartbeatCount++; DelegateState.TeartbeatServerStateInfo(TeartbeatCount); } catch (Exception ex) { DelegateState.ServerStateInfo("Error:类[DaemonThread]" + ex.Message); } } } }
/// <summary> /// 监控 /// </summary> public void StartAccept() { //异步操作 //m_sListen.BeginReceiveFrom( //m_sListen.Buffer, 0, state.Buffer.Length, //m_sListen.None, //ref m_sListen.RemoteEP, //EndReceiveFromCallback, //state); m_sListen.ReceiveFrom(BufferData, ref RemoteEndPoint); semap.WaitOne(); if (BufferData[0] == 0x1) { string username = Encoding.UTF8.GetString(BufferData, 1, BufferData.Length); SocketUserUDP userUdp = new SocketUserUDP(); userUdp.ipEndPoint = RemoteEndPoint; userUdp.ActiveDateTime = DateTime.Now; userUdp.UserName = username; userUdp.password = username; if (userUdp.password.Length > 4) { //密码小于4是设备 DeviceInfoList.Add(userUdp); DelegateState.ServerStateInfo(RemoteEndPoint.ToString() + "远端设备连接"); } else { UserInfoList.Add(userUdp); DelegateState.ServerStateInfo(RemoteEndPoint.ToString() + "远端用户连接"); } m_sListen.SendTo(Encoding.UTF8.GetBytes("连接成功!"), RemoteEndPoint); DelegateState.ServerConnStateInfo(RemoteEndPoint.ToString(), "UDP"); } else if (BufferData[0] == 0x2) { string username = Encoding.UTF8.GetString(BufferData, 1, BufferData.Length); foreach (SocketUserUDP user in DeviceInfoList) { if (user.UserName == username) { user.ActiveDateTime = DateTime.Now; m_sListen.SendTo(Encoding.UTF8.GetBytes(user.ipEndPoint.ToString()), RemoteEndPoint); DelegateState.ServerStateInfo(RemoteEndPoint.ToString() + "远端用户:" + user.UserName + "搜索设备."); } } } else if (BufferData[0] == 0x3) { string username = Encoding.UTF8.GetString(BufferData, 1, BufferData.Length); foreach (SocketUserUDP user in UserInfoList) { if (user.UserName == username) { DeviceInfoList.Remove(user); DelegateState.ServerStateInfo("UDP:" + RemoteEndPoint.ToString() + "远端用户退出"); break; } } } else { DelegateState.ServerStateInfo("UDP:" + RemoteEndPoint.ToString() + "发送空数据"); } semap.Release(); StartAccept(); }
/// <summary> /// 协议组装/继续接收 /// </summary> /// <param name="buffer">byte[]</param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public virtual bool ProcessReceive(byte[] buffer, int offset, int count) //接收异步事件返回的数据,用于对数据进行缓存和分包 { //m_activeDT = DateTime.UtcNow; //DynamicBufferManager receiveBuffer = m_socketUserToken.ReceiveBuffer; //receiveBuffer.WriteBuffer(buffer, offset, count);//把刚刚接收的信息加入到缓存中 //bool result = true; ////按照长度分包 //int packetLength = BitConverter.ToInt32(receiveBuffer.Buffer, 0); //获取包长度 //if ((packetLength > 10 * 1024 * 1024) | (receiveBuffer.DataCount > 10 * 1024 * 1024)) //最大Buffer异常保护 // return false; //if (receiveBuffer.DataCount >= packetLength) //packetLength收到的数据达到包长度 //{ // //命令 组装-如果组装失败则继续接收:如果组装成功-则删除 // result = ProcessPacket(receiveBuffer.Buffer, offset, packetLength); // if (result) // receiveBuffer.Clear(packetLength);//清理已经处理的协议 // else // return result; //} //return true; ///////////******下面的程序考虑粘包的情况。******////// m_activeDT = DateTime.UtcNow; DynamicBufferManager receiveBuffer = m_socketUserToken.ReceiveBuffer; receiveBuffer.WriteBuffer(buffer, offset, count); bool result = true; while (true) { if (receiveBuffer.Buffer.Length > 11) { // int packetLength = (int)((receiveBuffer.Buffer[1] << 8) | receiveBuffer.Buffer[2]); int packetLength = getLength(receiveBuffer.Buffer[11]); // Console.WriteLine(packetLength+"-------------------"); //if ((packetLength > 10 * 1024 * 1024) | (receiveBuffer.DataCount > 10 * 1024 * 1024)) if ((packetLength > 16064)) { DelegateState.ServerStateInfo("(packetLength > 16064 packetLength= " + packetLength.ToString()); return(false); } if ((receiveBuffer.DataCount > 10 * 1024 * 1024)) { DelegateState.ServerStateInfo("(receiveBuffer.DataCount> 10 * 1024* 1024 receiveBuffer.DataCount > 10 * 1024* 1024 "); return(false); } if (packetLength == 0) { return(false); } if (receiveBuffer.DataCount >= packetLength) { // while (1) { result = ProcessPacket(receiveBuffer.Buffer, offset, packetLength); if (result) { receiveBuffer.Clear(packetLength); if (receiveBuffer.DataCount > 0) { continue; } else { break; } } else { return(result); } } } else { return(true); } } else { return(true); } } return(true); }