/* 发送发送完毕包 */ public void SendFinish(int numberRandom, int blockRandom, int littleRandom) { byte[] buffer = new byte[FinishTip[0]]; // 填充发送完毕包标识 ByteChange.StringToByte(datagramFinish, buffer, FinishTip[1], 4); // 填充次随机数 ByteChange.IntToByte(buffer, FinishTip[2], numberRandom); // 填充块随机数 ByteChange.IntToByte(buffer, FinishTip[3], blockRandom); // 填充小随机数 ByteChange.IntToByte(buffer, FinishTip[4], littleRandom); // 填充报尾 ByteChange.StringToByte(datagramTail, buffer, FinishTip[5], 4); try { //DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(yourAddress), // yourPort); //socket.send(packet); sendState.AddNumHaveSendBytes(buffer.Length); udpSendClient.Send(buffer, buffer.Length, host); } catch (Exception ex) { log.Error(ex.ToString()); //logger.error("{}", ex); } }
/*发送分组头确认包*/ public void SendDatagramHeadAck(int numberRandom, int blockRandom) { // System.out.println("发送分组头确认包"); byte[] buffer = new byte[HeadAckTip[0]]; //DatagramPacket packet = null; //填充分组头确认包标识 ByteChange.StringToByte(datagramHeadAck, buffer, HeadAckTip[1], 4); //填充次随机数 ByteChange.IntToByte(buffer, HeadAckTip[2], numberRandom); //填充块随机数 ByteChange.IntToByte(buffer, HeadAckTip[3], blockRandom); //填充报尾 ByteChange.StringToByte(datagramTail, buffer, HeadAckTip[4], 4); //填充完成,发送报文 try { //packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(yourAddress), yourPort); //socket.send(packet); udpReceiveClient.Send(buffer, buffer.Length, host); } catch (Exception ex) { log.Error(ex.ToString()); //Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex); } }
/* 发送分组包,无回送 */ 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 SendStartAck(int numberRandom) { //DatagramPacket sendPacket = null; byte[] sendBuffer = new byte[StartAckTip[0]]; //填充标识 ByteChange.StringToByte(datagramStartAck, sendBuffer, StartAckTip[1], 4); //填充次随机数 ByteChange.IntToByte(sendBuffer, StartAckTip[2], numberRandom); //填充报尾 ByteChange.StringToByte(datagramTail, sendBuffer, StartAckTip[3], 4); try { udpReceiveClient.Send(sendBuffer, sendBuffer.Length, host); } catch (Exception ex) { // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); //logger.error("{}", ex); log.Error(ex.ToString()); } }
/* 发送结束传输包 */ public void SendOver(int numberRandom) { // 设定接收超时1ms udpSendClient.Client.ReceiveTimeout = sendState.WaitTime; // 生成传输结束包 //DatagramPacket packetOver, packetOverAck; byte[] overBuffer = new byte[StopTip[0]]; byte[] overAckBuffer = new byte[StopAckTip[0]]; // 填充标识 ByteChange.StringToByte(datagramStop, overBuffer, StopTip[1], datagramStop.Length); // 填充次随机数 ByteChange.IntToByte(overBuffer, StopTip[2], numberRandom); // 填充报尾 ByteChange.StringToByte(datagramTail, overBuffer, StopTip[3], datagramTail.Length); try { while (true) { try { udpSendClient.Send(overBuffer, overBuffer.Length, host); // sendState.addHaveSendBytes(packetOver.getLength()); sendState.AddNumHaveSendBytes(overAckBuffer.Length); ByteChange.CleanByte(overAckBuffer); overAckBuffer = udpSendClient.Receive(ref host); // 检查ACK标识 String str = Encoding.Default.GetString(overAckBuffer, StopAckTip[1], 4); if (!datagramStopAck.Equals(str)) { continue; } // 检查次随机数 int num = ByteChange.ByteToInt(overAckBuffer, StopAckTip[2]); if (num != numberRandom) { continue; } break; } catch (SocketException ex) { if (ex.ErrorCode == 10060) { continue; } //MessageBox.Show(ex.ToString()); //if (ex is TimeoutException) //{ // continue; // // 接收超时,则继续循环 //} //if(ex is SocketException) //{ // continue; //} } } } catch (Exception ex) { //logger.error("{}", ex); log.Error(ex.ToString()); } }
/* 发送分组头 */ 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 void SendStart(int numberRandom) { //log.Info("SendStart进入"); byte[] sendBuffer = new byte[StartTip[0]]; byte[] receiveBuffer = new byte[StartAckTip[0]]; // 填充开始传输包 ByteChange.StringToByte(datagramStart, sendBuffer, StartTip[1], 4); ByteChange.IntToByte(sendBuffer, StartTip[2], numberRandom); ByteChange.StringToByte(datagramTail, sendBuffer, StartTip[3], 4); // 设置超时1ms及初始化数据包 bool canSend = true; while (true) { try { if (canSend) { udpSendClient.Client.ReceiveTimeout = sendState.WaitTime; udpSendClient.Send(sendBuffer, sendBuffer.Length, host); sendState.AddNumHaveSendBytes(sendBuffer.Length); } receiveBuffer = udpSendClient.Receive(ref host); // 如果接收到数据包,无论如何,下一次都不能发送 canSend = false; // 判断标识 String str = Encoding.Default.GetString(receiveBuffer, StartAckTip[1], 4); if (!datagramStartAck.Equals(str)) { continue; } // 判断次随机数 int num = ByteChange.ByteToInt(receiveBuffer, StartAckTip[2]); if (num != numberRandom) { continue; } // 否则接收成功,退出循环 int time = sendState.WaitTime; if (time <= 2000 && time >= 4) { sendState.WaitTime = time / 2;//延迟时间减半 } // logger.info("WaitTime={}",sendState.getWaitTime()); //log.Info("SendStart退出"); break; } catch (SocketException e) { if (e.ErrorCode == 10060) { canSend = true; int time = sendState.WaitTime; if (time <= 1800 && time > 0) { sendState.WaitTime = (time + 10);//延迟时间+10 } } //MessageBox.Show(e.ToString()); //if (e is TimeoutException) //{ // canSend = true; // //int time = sendState.getWaitTime(); // //if (time <= 1800 && time > 0) // //{ // // sendState.setWaitTime(time + 10);//延迟时间+10 // //} // // logger.info("WaitTime={}",sendState.getWaitTime()); //} //if(e is SocketException) //{ //} } } // System.out.println("开始发送包发送完毕退出"); }
/*发送传输结束确认包*/ public void SendOverAck(int numberRandom) { //DatagramPacket packetOverAck = null, packetOver = null; byte[] sendBuffer = new byte[StopAckTip[0]]; byte[] receiveBuffer = new byte[StopTip[0]]; //设置接收超时1000ms try { //socket.setSoTimeout(1000); udpReceiveClient.Client.ReceiveTimeout = 1000; /*填充结束确认包*/ //填充确认包标识 ByteChange.StringToByte(datagramStopAck, sendBuffer, StopAckTip[1], 4); //填充次随机数 ByteChange.IntToByte(sendBuffer, StopAckTip[2], numberRandom); //填充报尾 ByteChange.StringToByte(datagramTail, sendBuffer, StopAckTip[3], 4); /*填充完毕*/ //packetOverAck = new DatagramPacket(sendBuffer, sendBuffer.length, InetAddress.getByName(yourAddress), yourPort); //packetOver = new DatagramPacket(receiveBuffer, receiveBuffer.length); } catch (Exception ex) { log.Error(ex.ToString()); // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); //logger.error("{}", ex); } bool canSendAck = true; while (true) { try { if (canSendAck) { //socket.send(packetOverAck); udpReceiveClient.Send(sendBuffer, sendBuffer.Length, host); } ByteChange.CleanByte(receiveBuffer); //socket.receive(packetOver); receiveBuffer = udpReceiveClient.Receive(ref host); //receiveState.addHaveReceiveBytes(packetOver.getLength()); // System.out.println("Over:收到包,IP"+packetOver.getAddress()); //如果接收到传输结束包,就继续循环 //String str = new String(receiveBuffer, StopTip[1], 4); // System.out.println("Over:收到包,str"+str); String str = Encoding.Default.GetString(receiveBuffer, StopTip[1], 4); //if (str.equals(datagramStop)) if (datagramStop.Equals(str)) { //检查次随机数 int num = ByteChange.ByteToInt(receiveBuffer, StopTip[2]); if (num == numberRandom) { canSendAck = true; continue; } } //如果收到开始传输包,并且其次随机数与这次的不一样,则退出 //if (str.equals(datagramStart)) if (datagramStart.Equals(str)) { //检查次随机数 if (ByteChange.ByteToInt(receiveBuffer, StartTip[2]) != numberRandom) { break; } } //如果是其他包,也继续循环,但是一下轮不发送确认包 canSendAck = false; continue; } catch (Exception e) { if (e is TimeoutException) { //如果接收超时,则退出循环 // System.out.println("接收超时"); break; } if (e is SocketException) { break; } } } }
/*发送请求重发包*/ 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); }