Exemplo n.º 1
0
 public List <P2PMessage> GetReply(int maxReplyMessage)
 {
     ReadToBuffer(maxReplyMessage);
     return(P2PMessage.GenFromMS(ms));
 }
Exemplo n.º 2
0
        void handleLoop(TcpClient client)
        {
            System.Timers.Timer t  = new System.Timers.Timer(200);
            var       s            = client.GetStream();
            bool      ifClose      = false;
            Stopwatch stopwatch    = new Stopwatch();
            var       continueTime = 0L;
            bool      ifAlive      = true;

            while (!ifClose && client.Connected)
            {
                if (continueTime > 500)
                {
                    if (ifAlive)
                    {
                        continueTime = 0;
                        ifAlive      = false;
                    }
                    else
                    {
                        ifClose = true;
                        break;
                    }
                }
                stopwatch.Start();
                try
                {
                    _logger.Info("enter loop");
                    var waitConstant = 1;
                    var count        = 0;
                    var ms           = new MemoryStream();
                    var length4Read  = -1;
                    while (count < waitConstant)
                    {
                        client.ReceiveTimeout = 100;

                        // 如果想要调节缓冲区大小,修改此变量
                        var buffer_size = 5000;
                        var buffer      = new byte[buffer_size];
                        var size        = 0;
                        do
                        {
                            if (length4Read == 0)
                            {
                                count++;
                                break;
                            }
                            else if (length4Read == -1)
                            {
                                size        = s.Read(buffer, 0, 8);
                                length4Read = P2PMessage.TryParseHeader(buffer);
                                if (BitConverter.ToInt32(buffer) == (int)P2PMessageType.GET_OK)
                                {
                                    waitConstant = 2;
                                }
                                else
                                {
                                    waitConstant = 1;
                                }
                            }
                            else
                            {
                                var read_size = (length4Read > buffer_size) ? buffer_size : length4Read;
                                size        = s.Read(buffer, 0, read_size);
                                length4Read = length4Read - size;
                            }
                            ms.Write(buffer, 0, size);
                            _logger.Info($"now recv buffer is {BitConverter.ToString(ms.ToArray())}, length for read is {length4Read}, count is {count}");
                        } while (s.DataAvailable);
                    }
                    var what = P2PMessage.GenFromMS(ms);
                    foreach (var i in what)
                    {
                        ifAlive = true;
                        _logger.Info($"recive message : {i.type}");
                        if (i.type == P2PMessageType.GET_FILE_INFO)
                        {
                            var hash = ((GetFileInfoMessage)i).hash;
                            // 在这里,我使用绑定到TCP四元组的本机地址作为传回的本机地址。
                            var localAddress = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
                            SendFileInfoMessage(fmanager.ProvideLocateInfo(hash, localAddress), hash, client);
                        }
                        else if (i.type == P2PMessageType.GET_DATA)
                        {
                            var    message = (GetDataMessage)i;
                            var    hash    = message.hash;
                            var    indexs  = message.what;
                            byte[] send_buffer;
                            try
                            {
                                foreach (var index in indexs)
                                {
                                    send_buffer = fmanager.ProvideFileData(hash, index);
                                    send(new DataMessage(send_buffer, hash, index), client);
                                }
                            }
                            catch (BlockNotPresentException)
                            {
                                send(new ErrorMessage(hash, indexs[0]), client);
                            }
                        }
                        else if (i.type == P2PMessageType.GET_OK)
                        {
                            var message   = (OKMessage)i;
                            var remote_ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
                            fmanager.SetRemoteBlockPresentStat(
                                message.block.hashOfFile,
                                remote_ip,
                                message.block.index,
                                true);
                        }
                        else if (i.type == P2PMessageType.CLOSE)
                        {
                            ifClose = true;
                        }
                    }
                }
                catch (IOException)
                {
                    _logger.Debug($"timeout for receive : {client.Client.RemoteEndPoint}");
                    break;
                }
                stopwatch.Stop();
                continueTime += stopwatch.ElapsedMilliseconds;
            }
        }