/// <summary> /// 通过ip发送信息给客户端 /// </summary> /// <param name="ip"></param> /// <param name="msg"></param> public bool SendMsgToClientForIP(string ip, string msg) { lockSlim.EnterReadLock(); bool isok = true; try { if (dictsocket.ContainsKey(ip.Trim())) { ClientMode clientMode = dictsocket[ip.Trim()]; if (SocketTools.IsSocketConnected(clientMode.socket)) { clientMode.socket.Send(SocketTools.GetBytes(msg, IsOpenDesEnc)); isok = true; } else { clientMode.socket.Close(); OnDebug?.Invoke($"The client with ip {clientMode.ip} has logged out and can't send a message."); isok = false; } } } catch (Exception ex) { OnError?.Invoke($"Error when sending to the client:{ex.ToString()}"); isok = false; } finally { lockSlim.ExitReadLock(); } return(isok); }
/// <summary> /// 接收信息 /// </summary> /// <param name="socket"></param> private void RecMsg(object socket) { int headSize = 4; byte[] surplusBuffer = null; System.Net.Sockets.Socket sokClient = socket as System.Net.Sockets.Socket; string socketip = sokClient.RemoteEndPoint.ToString(); while (true) { int count = -1; try { byte[] vs = new byte[1024]; count = sokClient.Receive(vs); // 接收数据,并返回数据的长度; int bytesRead = vs.Length; if (bytesRead > 0) { if (surplusBuffer == null) { surplusBuffer = vs; } else { surplusBuffer = surplusBuffer.Concat(vs).ToArray(); } int haveRead = 0; int totalLen = surplusBuffer.Length; while (haveRead <= totalLen) { if (totalLen - haveRead < headSize) { //Console.WriteLine("不够一个包~"); byte[] byteSub = new byte[totalLen - haveRead]; Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead); surplusBuffer = byteSub; totalLen = 0; break; } //如果是够一个完整包了,帽读取包头的数据 byte[] headByte = new byte[headSize]; Buffer.BlockCopy(surplusBuffer, haveRead, headByte, 0, headSize); int bodySize = BitConverter.ToInt32(headByte, 0); //得到长度 if (bodySize == 0) { surplusBuffer = null; totalLen = 0; break; } //这里的 haveRead=等于N个数据包的长度 从0开始;0,1,2,3....N //如果自定义缓冲区拆解N个包后的长度 大于 总长度,说最后一段数据不够一个完整的包了,拆出来保存 if (haveRead + headSize + bodySize > totalLen) { byte[] byteSub = new byte[totalLen - haveRead]; Buffer.BlockCopy(surplusBuffer, haveRead, byteSub, 0, totalLen - haveRead); surplusBuffer = byteSub; // Console.WriteLine("不够一个包,拆出来保存"); break; } else { string strc = Encoding.UTF8.GetString(surplusBuffer, haveRead + headSize, bodySize).StringDecrypt(IsOpenDesEnc); string[] ss = strc.Split(','); //心跳事件,更新客户端的最后登陆时间 if (ss.Count() == 2 && ss[0].ToString().Equals("hear")) { // 心跳事件 0=hert,1=ip lockSlim.EnterWriteLock(); try { ClientMode socketClient; if (dictsocket.TryGetValue(ss[1].ToString(), out socketClient)) { OnDebug?.Invoke($"Update timestamp:{SocketTools.GetTimeStamp()} - ss[1].ToString()"); socketClient.lastTickTime = SocketTools.GetTimeStamp(); } } catch (Exception ex) { OnError?.Invoke($"Heartbeat error: {ex.ToString()}"); } finally { lockSlim.ExitWriteLock(); } } else { // OnRecMessage?.Invoke(socketip, strc); OnRecMessage?.Invoke(this, new SocketMsgArgs(new ClientRecInfo() { ip = socketip, msg = strc })); } haveRead = haveRead + headSize + bodySize; if (headSize + bodySize == bytesRead) { surplusBuffer = null; totalLen = 0; } } } } } catch (Exception ex) { ReMoveSocketClient(socketip); //OnError?.Invoke($"Client thread error:{socketip} " ); break; } } }