/* 发送发送完毕包 */
 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 int ReceiveStart()
 {
     //DatagramPacket sendPacket = null, receivePacket = null;
     //用于发送开始确认包
     byte[] sendBuffer = new byte[StartAckTip[0]];
     //用于接收开始传输包
     byte[] receiveBuffer = new byte[FilePropertyTip[0]];
     try
     {
         udpReceiveClient.Client.ReceiveTimeout = 0;
     }
     catch (Exception e) {
         log.Error("ReceiveStart", e);
     }
     while (true)
     {
         try
         {
             //socket.receive(receivePacket);
             receiveBuffer = udpReceiveClient.Receive(ref host);
             receiveState.AddHaveReceiveBytes(receiveBuffer.Length);
             //检查标识
             String str = Encoding.Default.GetString(receiveBuffer, StartTip[1], 4);
             if (!datagramStart.Equals(str))
             {
                 continue;
             }
             //获取次随机数
             int numberRandom = ByteChange.ByteToInt(receiveBuffer, StartTip[2]);
             SendStartAck(numberRandom);
             //                System.out.println("接收到开始传输包");
             return(numberRandom);
         }
         catch (Exception ex)
         {
             //                Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex);
             //logger.error("{}", ex);
             //MessageBox.Show(ex.ToString());
             log.Error(ex.ToString());
         }
     }
 }
 /* 发送分组包,无回送 */
 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 bool GetDatagramReq(int numberRandom, int blockRandom, int littleRandom, bool[] sendTip)
        {
            //log.Info("GetDatagramReq进入");
            // 首先,设置接收超时5ms
            //DatagramPacket packetReq = null;
            // 由于请求重发包发送的是需要重发的分组
            // 所以,先将成功发送标记全部置true,再根据
            for (int i = 0; i < sendTip.Length; i++)
            {
                sendTip[i] = true;
            }
            // 请求重发包将发送失败的置false
            byte[] buffer        = new byte[ReqAgainTip[0]];
            bool   canSendFinish = true;

            while (true)
            {
                try
                {
                    if (canSendFinish)
                    {
                        udpSendClient.Client.ReceiveTimeout = sendState.WaitTime;
                        SendFinish(numberRandom, blockRandom, littleRandom);
                    }
                    ByteChange.CleanByte(buffer);
                    buffer = udpSendClient.Receive(ref host);
                    // 如果接收到数据包,不管是否正确,下一轮都不能发未接收请求重发包
                    canSendFinish = false;
                    // 对接收到的请法求重发包进行解析
                    // 检证是不是请求重发包
                    String s = Encoding.Default.GetString(buffer, ReqAgainTip[1], 4);
                    if (!datagramReqAgain.Equals(s))
                    {
                        continue;
                    }
                    // 匹配次随机数
                    int r = ByteChange.ByteToInt(buffer, ReqAgainTip[2]);
                    if (r != numberRandom)
                    {
                        continue;
                    }
                    // 匹配块随机数
                    r = ByteChange.ByteToInt(buffer, ReqAgainTip[3]);
                    if (r != blockRandom)
                    {
                        continue;
                    }
                    // //验证该包是否完整
                    // s=new String(buffer,1014,4);
                    // if(!s.equals(datagramTail)){
                    // continue;
                    // }
                    // 验证此请求重发包的小随机数是否与本次发送的"发送完毕包"相同
                    r = ByteChange.ByteToInt(buffer, ReqAgainTip[4]);
                    if (r != littleRandom)
                    {
                        continue;
                    }
                    // 验证完毕,提取请求重发的分组
                    // 提取数据长度
                    int length = ByteChange.ByteToShort(buffer, ReqAgainTip[5]);
                    // 如果数据长度是0,验证一下数据完整性,如果完整,则返回数据接收完毕
                    if (length == 0)
                    {
                        //s = new String(buffer, ReqAgainTip[5] + 2, 4);
                        s = Encoding.Default.GetString(buffer, ReqAgainTip[5] + 2, 4);
                        //if (s.equals(datagramTail))
                        if (datagramTail.Equals(s))
                        {
                            // 数据完整,返回
                            //log.Info("GetDatagramReq退出true");
                            return(true);
                        }
                        else
                        {
                            // 数据不完整,此包无效,继续循环
                            continue;
                        }
                    }
                    else
                    {
                        sendState.NumResendPackets = 0;
                        for (int i = 0; i < length; i++)
                        {
                            int tip = ByteChange.ByteToShort(buffer, i * 2 + ReqAgainTip[6]);
                            sendTip[tip] = false;
                            sendState.AddNumResendPackets();
                        }
                        //log.Info("GetDatagramReq退出");
                        break;
                    }
                }
                catch (SocketException ex)
                {
                    // Logger.getLogger(Send.class.getName()).log(Level.SEVERE,null, ex);
                    // 如果是接收超时,那么下一次循环就应该发送"发送完毕包"
                    if (ex.ErrorCode == 10060)
                    {
                        canSendFinish = true;
                        int time = sendState.WaitTime;
                        if (time <= 1800 && time > 0)
                        {
                            sendState.WaitTime = (time + 10);//延迟时间+10
                        }
                    }
                }
            }
            return(false);
        }
        /* 发送分组头 */
        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;
                    }
                }
            }
        }
        /*接收一个分组*/

        /*返回值说明:
         * 1.如果正常接收,返回读取数据的长度
         * 2.如果接收超时,返回-1  //此句已经无效
         * 3.如果接收到本分组的分组头,返回-2
         * 4.如果接收到新的发送完毕包,返回-3
         * 5.如果接收到上次的发送完毕包,返回-4
         * 6.其他情况,返回-5
         */
        //此函数只用于接收,不发送任何信息.遇到错误,只是将错误标识返回.
        //如果接收到的是分组包,将其存入buffer中相应位置,返回数据的长度
        public int GetDatagramData(int numberRandom, int random, byte[] buffer, bool[] receiveTip, int[] startTip)
        {
            //设置不接收超时
            //try
            //{
            //    socket.setSoTimeout(0);
            //}
            //catch (SocketException ex)
            //{
            //    //            Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex);
            //    logger.error("{}", ex);
            //}
            udpReceiveClient.Client.ReceiveTimeout = 0;
            byte[] receiveBuffer = new byte[DataTip[0]];
            //DatagramPacket packet = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            try
            {
                ByteChange.CleanByte(receiveBuffer);
                //socket.receive(packet);
                receiveBuffer = udpReceiveClient.Receive(ref host);
                //receiveState.addHaveReceiveBytes(packet.getLength());
                //就算收到未接收请求重发包,有意义的随机数也应该是与本分组随机数相同的
                //次随机数
                if (ByteChange.ByteToInt(receiveBuffer, DataTip[2]) != numberRandom)
                {
                    return(-5);
                }
                //所以,先判断块随机数
                int r = ByteChange.ByteToInt(receiveBuffer, DataTip[3]);
                if (r != random)
                {
                    return(-5);
                }
                //判断分组标识
                //String s = new String(receiveBuffer, DataTip[1], 4);
                String s = Encoding.Default.GetString(receiveBuffer, DataTip[1], 4);
                //if (!s.equals(datagramData))
                if (!datagramData.Equals(s))
                {
                    //如果此包不是分组包
                    //判断其是否是本分组的分组头.由于随机数已经匹配,所以,只需要判断标识
                    //if (s.equals(datagramHead))
                    if (datagramHead.Equals(s))
                    {
                        return(-2);
                    }
                    //再判断其是否是发送完毕包
                    //if (s.equals(datagramFinish))
                    if (datagramFinish.Equals(s))
                    {
                        //先判断,是否是新的发送完毕包
                        r = ByteChange.ByteToInt(receiveBuffer, FinishTip[4]);
                        if (!littleRandomStack.InIt(r))
                        {
                            littleRandomStack.Add(r);
                            return(-3);
                        }
                        //如果是上次的发送完毕包
                        int r2 = littleRandomStack.GetLast();
                        if (r2 != -1 && r2 == r)
                        {
                            return(-4);
                        }
                    }
                    //否则,返回-5
                    return(-5);
                }
                //至此已经是分组包了,先判断一下包的完整性
                //因为,如果包是不完整的,它的数据就是有问题的,是不能接收的
                //s = new String(receiveBuffer, DataTip[7], 4);
                s = Encoding.Default.GetString(receiveBuffer, DataTip[7], 4);
                //if (!s.equals(datagramTail))
                if (!datagramTail.Equals(s))
                {
                    return(-5);
                }
                //包是完整的,获取包的序号
                int serial = ByteChange.ByteToShort(receiveBuffer, DataTip[4]);
                int number = ByteChange.ByteToShort(receiveBuffer, DataTip[5]);
                //如果该序列的包未被正确接收
                if (!receiveTip[serial])
                {
                    receiveTip[serial] = true;
                    for (int i = 0; i < number; i++)
                    {
                        buffer[i + startTip[serial]] = receiveBuffer[i + DataTip[6]];
                    }
                    return(number);
                }
                //如果已经被正确接收了,则丢弃该包
                else
                {
                    return(-5);
                }
            }
            catch (Exception ex)
            {
                //Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
                if (ex is TimeoutException)
                {
                    return(-1);
                }
                if (ex is SocketException)
                {
                    return(-1);
                }
                return(-5);
            }
        }
        /*发送请求重发包*/
        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);
        }
        /*接收分组头*/
        //1.不接收超时. 2.接收成功,会调用发送分组头确认包
        public Rdh_return ReceiveDatagramHead(int numberRandom)
        {
            byte[] buffer = new byte[FilePropertyTip[0]];
            //DatagramPacket packet = null;
            Rdh_return rdh = new Rdh_return();

            //设置不接收超时

            udpReceiveClient.Client.ReceiveTimeout = 0;
            while (true)
            {
                try
                {
                    //packet = new DatagramPacket(buffer, buffer.length);//,InetAddress.getByName(yourAddress),yourPort
                    ByteChange.CleanByte(buffer);
                    //socket.receive(packet);
                    //receiveState.addHaveReceiveBytes(packet.getLength());
                    buffer = udpReceiveClient.Receive(ref host);
                    //检查分组头标识
                    //String str = new String(buffer, HeadTip[1], 4);
                    String str = Encoding.Default.GetString(buffer, HeadTip[1], 4);
                    //if (!str.equals(datagramHead))
                    if (!datagramHead.Equals(str))
                    {
                        /*既然不是分组头,重新接收是肯定的.只不过,有些情况,需要处理一下再重新接收*/
                        //如果是开始传输包
                        //if (str.equals(datagramStart))
                        if (datagramStart.Equals(str))
                        {
                            int num = ByteChange.ByteToInt(buffer, StartTip[2]);
                            if (num == numberRandom)
                            {
                                SendStartAck(numberRandom);
                                //                            System.out.println("在分组头中接收到开始传输包");
                                continue;
                            }
                        }
                        //如果是发送完毕包
                        //if (str.equals(datagramFinish))
                        if (datagramFinish.Equals(str))
                        {
                            //先检其次随机数
                            if (ByteChange.ByteToInt(buffer, FinishTip[2]) == numberRandom)
                            {
                                //检验是不是上一次的发送完毕包
                                //如果是的,说明上次发的0请求重发包没发成功
                                //先检查其块随机数是不是上一次的
                                if (randomStack.GetLast() != -1 && ByteChange.ByteToInt(buffer, FinishTip[3]) == randomStack.GetLast())
                                {
                                    //再检查其小随机数,是不是上次的(即最后一次发过来的)
                                    if (littleRandomStack != null)
                                    {
                                        //如果littelRandomStack是null,说明这是第一次接收分组头,当然不可能要重发
                                        if (littleRandomStack.GetLast() == ByteChange.ByteToInt(buffer, FinishTip[4]))
                                        {
                                            //如果小随机数也匹配,则发送上次的0请求重发包
                                            if (lastReqAgainBuffer != null)
                                            {
                                                //socket.send(lastReqAgain);
                                                udpReceiveClient.Send(lastReqAgainBuffer.ToArray(), lastReqAgainBuffer.Count, host);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //如果是传输结束包,则将0分组数量填充入rdh,然后返回
                        //if (str.equals(datagramStop))
                        if (datagramStop.Equals(str))
                        {
                            rdh.Number = 0;
                            return(rdh);
                        }
                        continue;
                    }
                    //检查该包是否完整
                    //str = new String(buffer, HeadTip[5], 4);
                    str = Encoding.Default.GetString(buffer, HeadTip[5], 4);
                    //if (!str.equals(datagramTail))
                    if (!datagramTail.Equals(str))
                    {
                        continue;
                    }
                    //检查完毕,获取随机数
                    rdh.Random = ByteChange.ByteToInt(buffer, HeadTip[3]);
                    //获取分组数量
                    rdh.Number = ByteChange.ByteToShort(buffer, HeadTip[4]);
                    SendDatagramHeadAck(numberRandom, rdh.Random);
                    break;
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                    //                Logger.getLogger(ReceiveLittle.class.getName()).log(Level.SEVERE, null, ex);
                    //logger.error("{}", ex);
                }
            }
            return(rdh);
        }