/** * 接收文件属性包 * @return */ //public FileProperty receiveFileProperty() //{ // //DatagramPacket receivePacket = null; // //用于接收开始传输包 // byte[] receiveBuffer = new byte[FilePropertyTip[0]]; // try // { // //socket.setSoTimeout(0); // //receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); // udpReceiveClient.Client.ReceiveTimeout = 0; // } // catch (Exception e) { // } // while (true) // { // try // { // //socket.receive(receivePacket); // //receiveState.addHaveReceiveBytes(receivePacket.getLength()); // receiveBuffer = udpReceiveClient.Receive(ref host); // //检查标识 // //String str = new String(receiveBuffer, FilePropertyTip[1], 4); // String str = Encoding.Default.GetString(receiveBuffer, FilePropertyTip[1], 4); // //if (!str.equals(datagramFileProperty)) // if(!datagramFileProperty.Equals(str)) // { // continue; // } // FileProperty fp = new FileProperty(); // //获取次随机数 // int numberRandom = ByteChange.byteToInt(receiveBuffer, FilePropertyTip[2]); // fp.FileLength = ByteChange.byteToLong(receiveBuffer, FilePropertyTip[3]); // int fileNameLength = ByteChange.byteToInt(receiveBuffer, FilePropertyTip[4]); // fp.FileName = ByteChange.ByteToString(receiveBuffer, FilePropertyTip[5], fileNameLength); // fp.MD5Str = ByteChange.ByteToString(receiveBuffer, FilePropertyTip[6], 32); // receiveState.setFileLength(fp.FileLength); // File f = new File(fp.FileName); // if (f.exists()) // { // logger.info("send md5:{}+receive md5:{}", fp.MD5Str, MD5.getFileMD5String(f)); // receiveState.setExistFileLength(f.length()); // if (fp.FileLength > f.length()) // { // fp.isOver = false; // fp.isExists = true; // logger.info("文件已存在,开始断点续传"); // sendBreakPoint(numberRandom, f, fp); // } // else if (fp.FileLength == f.length()) // { // if (fp.MD5Str.equals(MD5.getFileMD5String(f))) // {//MD5一样 // fp.isOver = true; // fp.isExists = true; // logger.info("文件已传输完成"); // sendBreakPoint(numberRandom, f, fp); // } // else // { // fp.isOver = false; // fp.isExists = false; // logger.info("文件出错,重新接受"); // sendFilePropertyAck(numberRandom); // } // } // else // { // fp.isOver = false; // fp.isExists = false; // logger.info("文件出错,重新接受"); // sendFilePropertyAck(numberRandom); // } // } // else // { // fp.isOver = false; // fp.isExists = false; // sendFilePropertyAck(numberRandom); // System.out.println("文件不存在,接收到文件属性包"); // } // return fp; // } // catch (Exception ex) // { // // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); // logger.error("{}", ex); // } // } //} //private void SendBreakPoint(int numberRandom, File f, FileProperty fp) //{ // DatagramPacket sendPacket = null; // byte sendBuffer[] = new byte[FileBreakPointTip[0]]; // //填充标识 // ByteChange.StringToByte(datagramFileBreakPoint, sendBuffer, FileBreakPointTip[1], 4); // //填充次随机数 // ByteChange.intToByte(sendBuffer, FileBreakPointTip[2], numberRandom); // //填充文件长度 // ByteChange.longToByte(sendBuffer, FileBreakPointTip[3], fp.FileLength); // //填充已传文件长度 // ByteChange.longToByte(sendBuffer, FileBreakPointTip[4], f.length()); // //填充报尾 // ByteChange.StringToByte(datagramTail, sendBuffer, FileBreakPointTip[5], 4); // try // { // sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, InetAddress.getByName(yourAddress), yourPort); // socket.send(sendPacket); // } // catch (Exception ex) // { // // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); // logger.error("{}", ex); // } //} // // private int punchDirectAckToClient(DatagramPacket dp, byte[] receiveBuffer) { // // TODO Auto-generated method stub // int randNum = ByteChange.byteToInt(receiveBuffer, CTCPunchDirectTip[2]); // long sID = ByteChange.byteToLong(receiveBuffer, CTCPunchDirectTip[3]); // long rID = ByteChange.byteToLong(receiveBuffer, CTCPunchDirectTip[4]); // String strTail=new String(receiveBuffer,CTCPunchDirectTip[5],4); // if(!strTail.equals(datagramTail)){ // return -1; // } // DatagramPacket sendPacket = null; // byte sendBuffer[] = new byte[CTCPunchDirectAckTip[0]]; // // 填充开始传输包 // ByteChange.StringToByte(datagramCTCPunchDirectAck, sendBuffer, CTCPunchDirectAckTip[1], 4); // ByteChange.intToByte(sendBuffer, CTCPunchDirectAckTip[2], randNum); // ByteChange.longToByte(sendBuffer, CTCPunchDirectAckTip[3], sID); // ByteChange.longToByte(sendBuffer, CTCPunchDirectAckTip[4], rID); // ByteChange.StringToByte(datagramTail, sendBuffer, CTCPunchDirectAckTip[5], 4); // try { // System.out.println("sendAck="+datagramCTCPunchDirectAck+randNum+sID+rID+datagramTail+dp.getAddress()+dp.getPort()); // sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, dp.getAddress(),dp.getPort()); // socket.send(sendPacket); // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // return 1; // } /*发送文件属性确认包*/ //public void sendFilePropertyAck(int numberRandom) //{ // DatagramPacket sendPacket = null; // byte sendBuffer[] = new byte[FilePropertyAckTip[0]]; // //填充标识 // ByteChange.StringToByte(datagramFilePropertyAck, sendBuffer, FilePropertyAckTip[1], 4); // //填充次随机数 // ByteChange.intToByte(sendBuffer, FilePropertyAckTip[2], numberRandom); // //填充报尾 // ByteChange.StringToByte(datagramTail, sendBuffer, FilePropertyAckTip[3], 4); // try // { // sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, InetAddress.getByName(yourAddress), yourPort); // socket.send(sendPacket); // } // catch (Exception ex) // { // // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); // logger.error("{}", ex); // } //} //文件属性内部类 //public class FileProperty //{ // public boolean isOver; // public long FileLength; // public String FileName; // public String MD5Str; // public boolean isExists; // FileProperty() // { // isOver = false; // FileLength = 0; // isExists = false; // } //} /*分组接收*/ public int ReceiveAll(byte[] littleBuffer) { byte[] buffer = new byte[dataLength * groupNum]; randomStack = new CircleStack(100); int numberRandom = ReceiveStart();//接收开始传输包 int allLength = 0; while (true) { int length = ReceiveGroup(numberRandom, buffer); if (length != -1) { for (int i = 0; i < length; i++) { littleBuffer[i + allLength] = buffer[i]; } allLength += length; } else { SendOverAck(numberRandom); // if(allLength==3){ // String end=new String(littleBuffer,0,3); // System.out.println("end-->"+end); // } //receiveState.addHavaReceivefileLength(allLength); return(allLength); } } }
/*接收一次分组*/ //返回值为该数组中数据的长度.并且,此函数进行传送结束的检查.发现结束,返回-1 public int ReceiveGroup(int numberRandom, byte[] buffer) { //接收分组头 Rdh_return rdh = ReceiveDatagramHead(numberRandom); // System.out.println("收到分组头,随机数:"+rdh.random+",分组数量:"+rdh.number); //记下随机数及分组数量 //int random = rdh.random; //int number = rdh.number; int random = rdh.Random; int number = rdh.Number; if (number == 0) { return(-1); } randomStack.Add(random); littleRandomStack = new CircleStack(100); //设定数据总长度 int lengthAll = 0; //由于只有最后一组的数据长度不是dataLength,所以,先计算前number-1个分组的总长度 lengthAll = dataLength * (number - 1); //用于记录成功接收了哪些分组 bool[] receiveTip = new bool[number]; for (int i = 0; i < number; i++) { receiveTip[i] = false; } //预先计算各组应存入buffer的起始下标 //由于除了最后一组,其它组的数据长度一定是dataLength.所以计算起始下标非常简单 int[] startTip = new int[number]; for (int i = 0; i < number; i++) { startTip[i] = i * dataLength; } //进入大循环,即连续去接收分组,直到所有分组完毕 while (true) { int result = GetDatagramData(numberRandom, random, buffer, receiveTip, startTip); // System.out.println("收到分组包"+result); //如果接收到的是一个分组.要记录其长度.由于,除了最后一组,其他的长度一定是dataLength //所以,如果这个length不是dataLength,说明是最后一组的长度 if (result > 0) { if (result != dataLength) { lengthAll += result; } continue; } //如果接收到是分组头 else if (result == -2) { //发送分组头确认包,然后循环 SendDatagramHeadAck(numberRandom, random); continue; } //如果是新的发送完毕包 else if (result == -3) { //发送请求重发包 //在发送请求重发包的时候,是要检查是否全部成功接收的,所以,这里不再重新检查,而是使用它检查的结果 bool flag = SendDatagramReqAgain(numberRandom, random, littleRandomStack.GetLast(), receiveTip); //System.out.println("发送请求重发包"); if (flag) { break; } continue; } //如果是上次的发送完毕包 else if (result == -4) { //如果上次发送的不是0请求重发包,则重发 //非0请求重发包的长度,一定是1018 //System.out.println("接收到上次的发送完毕包:"); try { if (lastReqAgainBuffer.Count == ReqAgainTip[0]) { //System.out.println("重发非0请求重发包"); //socket.send(lastReqAgain); udpReceiveClient.Send(lastReqAgainBuffer.ToArray(), lastReqAgainBuffer.Count, host); } } catch (Exception ex) { log.Error(ex.ToString()); //MessageBox.Show(ex.ToString()); // Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex); //logger.error("{}", ex); } continue; } } //这里有个很蛋疼的问题.由于不确定最后一组是否完整,只有在接收到最后一个分组时才知道其数据长度 //而接收分组是在单独的函数中完成,函数返回的是接收的数据长度.在循环中,如果发现数据长度不是dataLength //就认为它是最后一组,并将其长度加入lengthAll.但是,有一个严重的问题,因为,每个块,只有最后一个块的最后一个 //分组的数据长度可能不是dataLength.所以,前面的块,在进行计算的时候,有会忽略它最后一组的长度.导致以后的块 //连续错误 if (lengthAll == (number - 1) * dataLength) { lengthAll += dataLength; } return(lengthAll); }