// Use this for initialization public override void Init() { inited = true; netChan = new NetChan(); serverCommands = new char[CConstVar.MAX_RELIABLE_COMMANDS][]; for (int i = 0; i < CConstVar.MAX_RELIABLE_COMMANDS; i++) { serverCommands[i] = new char[CConstVar.MAX_STRING_CHARS]; } }
public void NetChanTransmitNextFrame(ref NetChan netChan) { MsgPacket send = new MsgPacket(); send.Oob = true; byte[] send_buf = new byte[CConstVar.PACKET_MAX_LEN]; int fragmentLength = 0; int outgoingSequence = netChan.outgoingSequence | CConstVar.FRAGMENT_BIT; send.WriteInt(outgoingSequence); //如果是客户端就发送qport if (netChan.src == NetSrc.CLIENT) { send.WriteInt(CConstVar.Qport); } send.WriteInt(CheckSum(netChan.challenge, netChan.outgoingSequence)); fragmentLength = CConstVar.FRAGMENT_SIZE; if (netChan.unsentFragmentStart + fragmentLength > netChan.unsentLength) { fragmentLength = netChan.unsentLength - netChan.unsentFragmentStart; } send.WriteShort((short)netChan.unsentFragmentStart); send.WriteShort((short)fragmentLength); send.WriteBufferData(netChan.unsentBuffer, -1, fragmentLength, netChan.unsentFragmentStart); //发送数据 SendPacket(netChan.src, send.CurSize, send.Data, netChan.remoteAddress); //存储发送的时间和大小 netChan.lastSentTime = CDataModel.InputEvent.Milliseconds(); netChan.lastSentSize = send.CurSize; if (CConstVar.ShowPacket > 0) { CLog.Info("%s send %d : s=%d fragment=%d,%d", netChan.src, send.CurSize, netChan.outgoingSequence, netChan.unsentFragmentStart, fragmentLength); } netChan.unsentFragmentStart += fragmentLength; //现在的情况有点戏剧,因为一个packet如果刚好是fragment的长度 //那还需要发送第二个packet(长度为0),这样另外一端就知道是否有更多的packet。 if (netChan.unsentFragmentStart == netChan.unsentLength && CConstVar.FRAGMENT_SIZE != fragmentLength) { netChan.outgoingSequence++; netChan.unsentFragments = false; } }
//发送的data数据是压缩过的,所以这里oob是true,不进行压缩 public void NetChanTransmit(ref NetChan netChan, int length, byte[] data) { MsgPacket send = new MsgPacket(); byte[] sendBuf = new byte[CConstVar.PACKET_MAX_LEN]; if (length > CConstVar.PACKET_MAX_LEN) { CLog.Info("Netchan transmit overflow, length = {0}", length); } netChan.unsentFragmentStart = 0; //fragment large reliable messages if (length >= CConstVar.FRAGMENT_SIZE) { netChan.unsentFragments = true; netChan.unsentLength = length; Array.Copy(data, 0, netChan.unsentBuffer, 0, length); //只发送第一帧的数据 NetChanTransmitNextFrame(ref netChan); } send.Oob = true; //写入packet header send.WriteInt(netChan.outgoingSequence); //发送qport if (netChan.src == NetSrc.CLIENT) //客户端发送到服务器需要qport { send.WriteShort((short)CConstVar.Qport); //这里qport跟本地监听端口一致 } send.WriteInt(CheckSum(netChan.challenge, netChan.outgoingSequence)); //checksum netChan.outgoingSequence++; send.WriteData(data, length); //data的数据写入到packet中 //发送数据 SendPacket(netChan.src, send.CurSize, send.Data, netChan.remoteAddress); //存储这个包发送的时间和大小。 netChan.lastSentTime = CDataModel.InputEvent.Milliseconds(); netChan.lastSentSize = send.CurSize; if (CConstVar.ShowPacket > 0) { CLog.Info("{0} send {1} : outgoSeq = {2} incomSeq = {3}", netChan.src, send.CurSize, netChan.outgoingSequence - 1, netChan.incomingSequence); } }
// public PlayerState playerState; public ClientNode(){ state = ClientState.FREE; netChan = new NetChan(); netChanQueue = new CircularBuffer<NetChanBuffer>(10); frames = new SvClientSnapshot[CConstVar.PACKET_BACKUP]; for(int i = 0; i < CConstVar.PACKET_BACKUP; i++){ frames[i] = new SvClientSnapshot(); } // gEntity = new SharedEntity(); // gEntity.r = new EntityShared(); // gEntity.s = new EntityState(); reliableCommands = new char[CConstVar.MAX_RELIABLE_COMMANDS][]; for(int i = 0; i < CConstVar.MAX_RELIABLE_COMMANDS; i++){ reliableCommands[i] = new char[CConstVar.MAX_STRING_CHARS]; } lastUserCmd = new UserCmd(); messageAcknowledge = -1; gamestateMessageNum = -1; // playerState = new PlayerState(); }
public static bool NetChanProcess(ref NetChan netChan, MsgPacket packet) { bool fragmented = false; int fragmentStart = 0; int fragmentLength = 0; packet.BeginReadOOB(); int sequence = packet.ReadInt(); //检查fragment信息 if ((sequence & CConstVar.FRAGMENT_BIT) != 0) { sequence &= ~CConstVar.FRAGMENT_BIT; fragmented = true; } else { fragmented = false; } //如果是服务器,那就读取qport if (netChan.src == NetSrc.SERVER) { packet.ReadShort(); // } int checkSum = packet.ReadInt(); //UDP欺骗保护 if (CheckSum(netChan.challenge, sequence) != checkSum) { return(false); } //读取fragment信息 if (fragmented) { fragmentStart = packet.ReadShort(); fragmentLength = packet.ReadShort(); } else { fragmentStart = 0; fragmentLength = 0; } if (CConstVar.ShowPacket > 0) { if (fragmented) { CLog.Info("{0} recv {1} bytes : s={2} fragment={3},{4}", netChan.src, packet.CurSize, sequence, fragmentStart, fragmentLength); } else { CLog.Info("{0} recv {1} bytes : s={2}", netChan.remoteAddress, packet.CurSize, sequence); } } //丢掉乱序或者重复的packets if (sequence <= netChan.incomingSequence) { if (CConstVar.ShowPacket > 0) { CLog.Error("%s:Out of order packet %d at %d", netChan.remoteAddress, netChan.dropped, sequence); } return(false); } //丢包使得当前的消息不可用 netChan.dropped = sequence - (netChan.incomingSequence + 1); if (netChan.dropped > 0) { if (CConstVar.ShowNet > 0 || CConstVar.ShowPacket > 0) { CLog.Info("{0}: Dropped {1} packets at {2}", netChan.remoteAddress, netChan.dropped, sequence); } } //如果当前是可靠消息的最后一个fragment //就取得incomming_reliable_sequence if (fragmented) { //确保以正确的顺序添加fragment,可能有packet被丢弃,或者过早地收到了这个packet //不会重新构造这个fragment,会等这个packet再次达到 if (sequence != netChan.fragementSequence) { netChan.fragementSequence = sequence; netChan.fragmentLength = 0; } //如果有fragment丢失,打印出日志 if (fragmentStart != netChan.fragmentLength) { if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0) { CLog.Info("{0}:Dropped a message fragment", netChan.remoteAddress); } return(false); } //复制fragment到fragment buffer if (fragmentLength < 0 || packet.CurPos + fragmentLength > packet.CurSize || netChan.fragmentLength + fragmentLength > netChan.fragmentBuffer.Length) { if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0) { CLog.Info("{0}:illegal fragment length", netChan.remoteAddress); } return(false); } netChan.WriteFragment(packet.Data, packet.CurPos, fragmentLength); //如果这不是最后一个fragment,就不处理任何事情(处于中间的fragment的长度是FRAGMENT_SIZE) if (fragmentLength == CConstVar.FRAGMENT_SIZE) { return(false); } // if (netChan.fragmentLength > packet.Data.Length) { if (CConstVar.ShowPacket > 0 || CConstVar.ShowNet > 0) { CLog.Info("{0}:fragmentLength {1} > packet.Data Length", netChan.remoteAddress, netChan.fragmentLength); } return(false); } //保证前面的还是sequence packet.WriteFirstInt(CNetwork.LittleInt(sequence)); packet.WriteBufferData(netChan.fragmentBuffer, 4, netChan.fragmentLength); // packet.CurSize = netChan.fragmentLength + 4; netChan.fragmentLength = 0; packet.CurPos = 4; //粘贴sequence packet.Bit = 32; //粘贴sequence //客户端没有应答fragment信息 netChan.incomingSequence = sequence; return(true); } //信息现在可以从当前的信息指针中读取 netChan.incomingSequence = sequence; return(true); }
private bool SV_NetChanProcess(ref NetChan netChan, MsgPacket msg) { return CNetwork.NetChanProcess(ref netChan, msg); }