/* 发送分组包,无回送 */ public void SendDatagramData(int numberRandom, int blockRandom, int serial, byte[] buffer, int start, int length) { //DatagramPacket packet = null; byte[] b = new byte[DataTip[0]]; // System.out.println("发送分组,序列号:" + serial); //assert length <= dataLength : "Error[发送分组包]:数据长度大于dataLength!"; if (length > dataLength) { throw new Exception("Error[发送分组包]:数据长度大于dataLength!"); } // 填充分组包标识 ByteChange.StringToByte(datagramData, b, DataTip[1], 4); // 填充次随机数 ByteChange.IntToByte(b, DataTip[2], numberRandom); // 填充块随机数 ByteChange.IntToByte(b, DataTip[3], blockRandom); // 填充分组序号 ByteChange.ShortToByte(b, DataTip[4], (short)serial); // 填充数据长度 ByteChange.ShortToByte(b, DataTip[5], (short)length); // 填充等传输的数据 for (int i = 0; i < length; i++) { b[i + DataTip[6]] = buffer[i + start]; } // 填充报尾 ByteChange.StringToByte(datagramTail, b, DataTip[7], 4); // 填充完毕,发送 try { //packet = new DatagramPacket(b, b.length, InetAddress.getByName(yourAddress), yourPort); //socket.send(packet); sendState.AddNumHaveSendBytes(b.Length); udpSendClient.Send(b, b.Length, host); } catch (Exception ex) { log.Error(ex.ToString()); //logger.error("{}", ex); } }
/* 发送分组头 */ public void SendDatagramHead(int numberRandom, int blockRandom, int number) { //log.Info("SendDatagramHead进入"); byte[] buffer = new byte[HeadTip[0]]; // 填充分组头标识 ByteChange.StringToByte(datagramHead, buffer, HeadTip[1], 4); // 填充次随机数 ByteChange.IntToByte(buffer, HeadTip[2], numberRandom); // 填充块随机数 ByteChange.IntToByte(buffer, HeadTip[3], blockRandom); // 写入数组数量 //assert number <= groupNum : "分组数量超过500"; if (number > groupNum) { throw new Exception("分组数量超过500"); } ByteChange.ShortToByte(buffer, HeadTip[4], (short)number); // 填充报尾标识 ByteChange.StringToByte(datagramTail, buffer, HeadTip[5], 4); // 发送分组头 // 发送后接收报头确认报,接收超时或者接收的不匹配则重发分组头 bool canSendHead = true; while (true) { try { if (canSendHead) { udpSendClient.Client.ReceiveTimeout = sendState.WaitTime; udpSendClient.Send(buffer, buffer.Length, host); sendState.AddNumHaveSendBytes(buffer.Length); } byte[] c = new byte[HeadAckTip[0]]; ByteChange.CleanByte(c); c = udpSendClient.Receive(ref host); // 只要接收到数据包,不论是不正确,下次循环就不能发送头 canSendHead = false; // 进行检查 // 1.检查其是否是分组头确认包 //String s = new String(c, HeadAckTip[1], 4); String s = Encoding.Default.GetString(c, HeadAckTip[1], 4); //if (!s.equals(datagramHeadAck)) if (!datagramHeadAck.Equals(s)) { continue; } // 2.检查其次随机数,是否与自己的匹配 int r = ByteChange.ByteToInt(c, HeadAckTip[2]); if (r != numberRandom) { continue; } // 3.检查其块随机数 r = ByteChange.ByteToInt(c, HeadAckTip[3]); if (r != blockRandom) { continue; } // 所有检查均正确,发送成功,返回 int time = sendState.WaitTime; if (time <= 2000 && time >= 4) { sendState.WaitTime = (time / 2);//延迟时间翻倍 } //logger.info("WaitTime={}",sendState.getWaitTime()); //log.Info("SendDatagramHead退出"); break; } catch (SocketException ex) { //MessageBox.Show(ex.ToString()); // Logger.getLogger(Send.class.getName()).log(Level.SEVERE, // null, ex); // 如果是接收超时,则一下次循环的时候,要先发送头 if (ex.ErrorCode == 10060) { canSendHead = true; int time = sendState.WaitTime; if (time <= 1800 && time > 0) { sendState.WaitTime = (time + 10);//延迟时间+10 } // logger.info("WaitTime={}",sendState.getWaitTime()); } //if (ex is TimeoutException) //{ // canSendHead = true; //} //if(ex is SocketException) //{ // canSendHead = true; //} //canSendHead = true; } } }
/*发送请求重发包*/ public bool SendDatagramReqAgain(int numberRandom, int blockRandom, int littleRandom, bool[] receiveTip) { //先判断是否全部接收成功 bool success = true; for (int i = 0; i < receiveTip.Length; i++) { if (receiveTip[i] == false) { success = false; break; } } byte[] buffer = new byte[ReqAgainTip[0]]; //DatagramPacket packet; //填充请求重发包标识 ByteChange.StringToByte(datagramReqAgain, buffer, ReqAgainTip[1], 4); //填充次随机数 ByteChange.IntToByte(buffer, ReqAgainTip[2], numberRandom); //填充块随机数 ByteChange.IntToByte(buffer, ReqAgainTip[3], blockRandom); //填充小随机数 ByteChange.IntToByte(buffer, ReqAgainTip[4], littleRandom); //填充数据长度 if (success) { //全部成功接收,所以应该发送的是0请求重发包 ByteChange.ShortToByte(buffer, ReqAgainTip[5], (short)0); //由于长度为0,所以没有数据,直接填充报尾 ByteChange.StringToByte(datagramTail, buffer, ReqAgainTip[6], 4); // System.out.println("未重传数据包"); } else { //解析receiveTip,遇到false就将下标存入buffer int length = 0; // int reqAgainCount = 0; //receiveState.setNumReceivePackets(receiveTip.length); //receiveState.setNumResendPackets(0); for (int i = 0; i < receiveTip.Length; i++) { if (receiveTip[i] == false) { ByteChange.ShortToByte(buffer, ReqAgainTip[6] + length * 2, (short)i); length++; //receiveState.addNumResendPackets(); } } // System.out.println("重传数据包数:"+reqAgainCount+"丢包率:"+(float)reqAgainCount/receiveTip.length); //填充数据长度 ByteChange.ShortToByte(buffer, ReqAgainTip[5], (short)length); //填充报尾 ByteChange.StringToByte(datagramTail, buffer, ReqAgainTip[7], 4); } try { //填充完毕,发送 if (success) { //packet = new DatagramPacket(buffer, ReqAgainTip[6] + 4, InetAddress.getByName(yourAddress), yourPort); udpReceiveClient.Send(buffer, ReqAgainTip[6] + 4, host); //buffer.CopyTo(lastReqAgainBuffer, ReqAgainTip[6] + 4); lastReqAgainBuffer.Clear(); lastReqAgainBuffer.AddRange(buffer); } else { //packet = new DatagramPacket(buffer, ReqAgainTip[0], InetAddress.getByName(yourAddress), yourPort); udpReceiveClient.Send(buffer, ReqAgainTip[0], host); lastReqAgainBuffer.Clear(); lastReqAgainBuffer.AddRange(buffer); //buffer.CopyTo(lastReqAgainBuffer, ReqAgainTip[0] + 4); } //lastReqAgainBuffer = buffer; //lastReqAgain = packet; ////System.out.println("发送请求重发包,长度"+lastReqAgain.getLength()); //socket.send(packet); } catch (Exception ex) { log.Error(ex.ToString()); // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); //logger.error("{}", ex); } return(success); }