public KcpNetPack Recv() { if (_recvPacks.ContainsKey(_recvIdx)) { _recvAckIdx = _recvIdx; KcpNetPack pack = _recvPacks[_recvIdx]; _recvPacks.Remove(_recvIdx);//清理内存 _recvIdx++; //SetHadCheck("Recv"); return(pack); } if (_sendNewIdx - _recvIdx > _range) { Debug.Log("Recv==>对方最新的发送序号:" + _sendNewIdx + ",正在接收处理的包序号:" + _recvIdx + ",R:" + _range); _reRecvTime++; if (_lastReRecvIdx != _recvIdx || _reRecvTime > RE_RECV_ACK_TIME) { _lastReRecvIdx = _recvIdx; _reRecvTime = 0; ReRecvAckIdx(_recvIdx); } if (_sendNewIdx - _recvIdx > MAX_DIS_CONNECTED_FS_NUM) { Disconnect("Recv"); } } return(null); }
public void Disconnect(string sReason) { Debug.LogFormat("NetUdpSocket Disconnect:{0}", sReason); if (sReason != "Server") { Kcp_DisConnect msg = new Kcp_DisConnect(); msg.Type = (int)Kcp_Net_Type.DscNormal; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.DisConnected); SocketSend(pack); } isConnected = false; isConnectting = false; try { //关闭线程 ConnectReceiveThread_Stop(); //最后关闭socket if (socket != null) { socket.Close(); } } catch (Exception e) { Debug.LogErrorFormat("Disconnect:{0}", e); } finally { lock (netEventList) { netEventList.Enqueue(NetworkEvent.disconnected); } } //Debug.Log("继续运行==============================>"); }
private void ReRecvAckIdx(int notAckIdx) { int iEndNotAckIdx = notAckIdx; for (int i = 1; i < MAX_DIS_CONNECTED_FS_NUM; i++) { if ((notAckIdx + i) > _sendNewIdx) { break; //大于对方最新的发送序号 } if (_recvPacks.ContainsKey(notAckIdx + i)) { break; //已经有数据了 } iEndNotAckIdx++; } Debug.Log("请求对方重发非ACK序号:" + notAckIdx + "-" + iEndNotAckIdx); Kcp_NotAckIndex msg = new Kcp_NotAckIndex(); msg.Startindex = notAckIdx; msg.Endindex = iEndNotAckIdx; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.NotAckIndex); SocketSend(pack); _lastRecvNotAckTime++; if (_lastRecvNotAckIdx != notAckIdx || _lastRecvNotAckTime > RE_RECV_NOT_ACK_TIME) { _lastRecvNotAckIdx = notAckIdx; _lastRecvNotAckTime = 0; UpCacheFSTime(); } }
public void Send(KcpNetPack pack) { _sendIdx++; var fsdata = pack.Assembly(); _sendPacks.Add(_sendIdx, fsdata.Bytes); RcpPackSendData(_sendIdx, _range); SetHadCheck("Send"); }
//public T Deserialize<T>() //{ // using (var ms = new MemoryStream(this.BodyBuffer.Bytes, 0, this.BodyBuffer.BufSize)) // return ProtoBuf.Serializer.Deserialize<T>(ms); //} //void Send<T>(Protocol type, T content) where T : Google.Protobuf.IMessage //{ // GameMessage message = new GameMessage(); // message.Type = type; // message.Data = ByteString.CopyFrom(content.ToByteArray()); // _UnityUdpSocket.Send(message.ToByteArray()); //} public static KcpNetPack SerializeToPack <T>(T content, ushort msg_id) where T : Google.Protobuf.IMessage { int size = content.CalculateSize();//注意检查长度不能超过 65,535-HeaderLength KcpNetPack pack = new KcpNetPack(msg_id, (ushort)size); pack.BodyBuffer = CBuffer.Create(size); pack.BodyBuffer.Fill(content.ToByteArray(), size); return(pack); }
private void RcpPackSendData(int iSendIdx, int iRange)//包含了iSendIdx的iRange个包 { if (!_sendPacks.ContainsKey(iSendIdx)) { return; } iRange = Math.Min(iRange, iSendIdx - _sendAckIdx); if (iRange <= 0) { return; } // Debug.Log("RcpPackSendData=========>" + iSendIdx + ",iRange:" + iRange); int iTime = iRange / MAX_DATA_CACHE + 1; int iStartIdx = iSendIdx - iRange; for (int i = 1; i <= iTime; i++) { int iSendIdx2, iRange2; if (iTime == i) { iSendIdx2 = iSendIdx; iRange2 = Math.Min(iRange - (i - 1) * MAX_DATA_CACHE, MAX_DATA_CACHE); if (iRange2 <= 0) { return; } } else { iSendIdx2 = iStartIdx + MAX_DATA_CACHE * i; iRange2 = MAX_DATA_CACHE; } Kcp_FsPackDatas msg = new Kcp_FsPackDatas(); msg.Ackindex = _recvAckIdx; msg.Sendindex = _sendIdx; for (int idx = (iSendIdx2 - iRange2 + 1); idx <= iSendIdx2; idx++) { if (idx < 0) { continue; } if (!_sendPacks.ContainsKey(idx)) { continue; } // Debug.Log("RcpPackSendData===>" + idx); Kcp_OneFsPackData fsPackData = new Kcp_OneFsPackData(); fsPackData.Index = idx; fsPackData.Fsdata = ByteString.CopyFrom(_sendPacks[idx]); msg.Fspackdata.Add(fsPackData); } //Debug.Log("RcpPackSendData=========>总序号:" + iSendIdx + ",总范围:" + iRange + ",序号" + iSendIdx2 + ",范围:" + iRange2 ); KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.FsInfoS); SocketSend(pack); } }
public void SocketSend(KcpNetPack pack) { if (!isConnected || isConnectting) { return; } var data = pack.Assembly(); socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd); _lastSendTime = System.Environment.TickCount; }
/*public void Flush() * { * if (_sendAckIdx < _sendIdx && _sendAckIdx > -1) * { * RcpPackSendData(_sendIdx, _range); * } * SetHadCheck(); * }*/ private void SynAckStatus() { if ((System.Environment.TickCount - _lastCheckTime > SYN_ACK_TIME && !_isSynAck) || System.Environment.TickCount - _lastSendTime > MUST_SYN_ACK_TIME) { //Debug.Log("同步Ack"); _isSynAck = true; Kcp_FsPackDatas msg = new Kcp_FsPackDatas(); msg.Ackindex = _recvAckIdx; msg.Sendindex = _sendIdx; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.SynAck); SocketSend(pack); } }
public Queue <KcpNetPack> RecvPacks(int iMaxNum) { Queue <KcpNetPack> recvPacks = new Queue <KcpNetPack>(); int iTime = iMaxNum; while (iTime > 0) { iTime--; KcpNetPack pack = Recv(); if (pack == null) { break; } recvPacks.Enqueue(pack); } return(recvPacks); }
public void OnUpdate() { if (isConnectting) { if (System.Environment.TickCount - _lastCheckFailTime > (CONNECTED_FAIL_TIME * (_tryConnectTime + 1))) { _tryConnectTime++; if (_tryConnectTime < MAX_CONNECT_TIME) { ConnectReceiveThread_Stop();//必须先关接收数据线程,再开.不然无法接收数据(待不需要关线程方案) Kcp_Connect msg = new Kcp_Connect(); msg.Quickconnect = _quickConnect; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.Connected); SetHadCheck("ReConnect"); var data = pack.Assembly(); socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd); _lastCheckFailTime = System.Environment.TickCount; Debug.LogErrorFormat("[链接失败]第{0}次尝试重新连接", _tryConnectTime); ConnectReceiveThread_Start(); } else { lock (netEventList) { netEventList.Enqueue(NetworkEvent.connectFail); } Debug.LogErrorFormat("[失败]第{0}次连接", _tryConnectTime); isConnectting = false; _tryConnectTime = 0; } } } lock (netEventList) { while (netEventList.Count > 0) { var e = netEventList.Dequeue(); listener.OnEvent(e); } } Check(); }
private void TestPing() { if (OBTAIN_PING) { if (_canNextPing && System.Environment.TickCount - _lastPingTime > PING_CHECK_TIME) { _pingIdx++; Kcp_Ping msg = new Kcp_Ping(); msg.Index = _pingIdx; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.PingIndex); SocketSend(pack); _lastPingTime = System.Environment.TickCount; _canNextPing = false; } else if (!_canNextPing && System.Environment.TickCount - _lastPingTime > PING_CHECK_TIME * 3) { _canNextPing = true; //恰好是测试ping丢包时候,这里做个超时重测功能 } } }
public void ConnectKCP(string host, int iport) { mHUDFPS = Facade.Instance.GetManager <HUDFPS>(FacadeConfig.ChildSystem_HUDFPS); _range = BASE_DATA_CACHE; ipEnd = new IPEndPoint(IPAddress.Parse(host), iport); socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //socket.Connect(ipEnd); IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); serverEnd = (EndPoint)sender; Kcp_Connect msg = new Kcp_Connect(); msg.Quickconnect = _quickConnect; KcpNetPack pack = KcpNetPack.SerializeToPack(msg, (ushort)Kcp_MsgID.Connected); SetHadCheck("Connect"); var data = pack.Assembly(); socket.SendTo(data.Bytes, data.Length, SocketFlags.None, ipEnd); isConnectting = true; isConnected = false; _lastCheckFailTime = System.Environment.TickCount; ConnectReceiveThread_Start(); }
//==========Rcp核心算法====================================================================== public void Input(byte[] buffer, int bufSize) { //List<NetPack> packs = DecodeBuffer(recvData, recvLen); //for (int i = 0; i < packs.Count; ++i) // Input(packs[i]); int offset1 = 0; int restCount2 = bufSize;// 剩余缓存大小 KcpNetPack pack = new KcpNetPack(); if (!pack.FillPack(buffer, ref offset1, ref restCount2)) { return; } Kcp_MsgID msgID = (Kcp_MsgID)pack.HeadID; if (msgID == Kcp_MsgID.NotAckIndex) { Kcp_NotAckIndex msg = Kcp_NotAckIndex.Parser.ParseFrom(pack.BodyBuffer.Bytes); Debug.Log("回复对方缺失的序号:" + msg.Startindex + "-" + msg.Endindex + ",对方已确认接收成功的Ack序号:" + _sendAckIdx); if (_sendAckIdx >= msg.Endindex) { return; } int iStartIndex = Math.Max(msg.Startindex, _sendAckIdx + 1); if (iStartIndex > msg.Endindex) { return; } _reSendTime++; if (_lastReSendIdx != iStartIndex || _reSendTime > RE_SEND_ACK_TIME) { _lastReSendIdx = iStartIndex; _reSendTime = 0; RcpPackSendData(msg.Endindex, msg.Endindex - iStartIndex + 1); } _lastSendNotAckTime++; if (_lastSendNotAckIdx != iStartIndex || _lastSendNotAckTime > RE_SEND_NOT_ACK_TIME) { _lastSendNotAckIdx = iStartIndex; _lastSendNotAckTime = 0; UpCacheFSTime(); } } else if (msgID == Kcp_MsgID.FsInfoS || msgID == Kcp_MsgID.SynAck) { Kcp_FsPackDatas msg = Kcp_FsPackDatas.Parser.ParseFrom(pack.BodyBuffer.Bytes); if (msg.Ackindex > _sendAckIdx) { _sendAckIdx = msg.Ackindex; } if (msg.Sendindex > _sendNewIdx) { _sendNewIdx = msg.Sendindex; } //if (msgID == Kcp_MsgID.FS_INFO_S) // Debug.Log("最新的已ACK序号确认==>" + _lastSendAckIdx + ",对方已确认接收成功的Ack序号:" + _sendAckIdx + "," + msg.ackindex + ",对方最新的发送序号:" + _sendNewIdx + "," + msg.sendindex); //else // Debug.Log("同步ACK状态==========>" + _lastSendAckIdx + ",对方已确认接收成功的Ack序号:" + _sendAckIdx + "," + msg.ackindex + ",对方最新的发送序号:" + _sendNewIdx + "," + msg.sendindex); for (int idx = _lastSendAckIdx; idx <= _sendAckIdx; idx++) { _sendPacks.Remove(idx);//清理内存 } _lastSendAckIdx = _sendAckIdx; int iMinIndex = -1; for (int i = 0; i < msg.Fspackdata.Count; i++) { Kcp_OneFsPackData fsPackData = msg.Fspackdata[i]; //Debug.Log("*************=1==>" + fsPackData.index); if (_recvPacks.ContainsKey(fsPackData.Index)) { continue; } if (_recvAckIdx >= fsPackData.Index) { continue; } //Debug.Log("*************=2==>" + fsPackData.index); int offset = 0; int restCount = 1024;// 剩余缓存大小 if (curPack2 == null) { curPack2 = new KcpNetPack(); } if (curPack2.FillPack(fsPackData.Fsdata.ToByteArray(), ref offset, ref restCount)) { if (fsPackData.Index < iMinIndex || iMinIndex == -1) { iMinIndex = fsPackData.Index; } _recvPacks[fsPackData.Index] = curPack2; curPack2 = null; } else { RcpPackSendData(fsPackData.Index, 2); Debug.LogErrorFormat("Input err: {0} ", fsPackData.Index); } } CheckPreorderLose(iMinIndex); DownCacheFSTime(); } else if (msgID == Kcp_MsgID.Connected || msgID == Kcp_MsgID.ReConnected) //暂时只有一次握手 { Kcp_Connect msg = Kcp_Connect.Parser.ParseFrom(pack.BodyBuffer.Bytes); if (_quickConnect != msg.Quickconnect) //防重复 { lock (netEventList) { netEventList.Enqueue(NetworkEvent.connected); } _quickConnect = msg.Quickconnect; } isConnected = true; isConnectting = false; _tryConnectTime = 0; Debug.Log("链接成功:" + _quickConnect); } else if (msgID == Kcp_MsgID.ConnectedFail) //暂时只有一次握手 { lock (netEventList) { netEventList.Enqueue(NetworkEvent.connectFail); } isConnected = false; isConnectting = false; Debug.Log("链接失败:CONNECTED_FAIL:"); } else if (msgID == Kcp_MsgID.DisConnected) //暂时只有一次挥手 { Kcp_DisConnect msg = Kcp_DisConnect.Parser.ParseFrom(pack.BodyBuffer.Bytes); if (msg.Type == (int)Kcp_Net_Type.DscErrAddr) { Debug.Log("链接断开:DSC_ERR_ADDR:" + _quickConnect); isConnectting = true; //快速重连/身份重新认证/更新IP地址 } else { Disconnect("Server"); } //Debug.Log("继续运行2==============================>"); } else if (msgID == Kcp_MsgID.PingIndex) { Kcp_Ping msg = Kcp_Ping.Parser.ParseFrom(pack.BodyBuffer.Bytes); if (msg.Index == _pingIdx) { Ping = System.Environment.TickCount - _lastPingTime; } UpdateNetInfo(""); //Debug.Log("Ping==============================>" + Ping); _canNextPing = true; } else { Debug.LogErrorFormat("Input err2: {0} ", msgID); return; } SetHadCheck("Input"); }
public void SendPack(KcpNetPack pack) { Send(pack); }