Beispiel #1
0
        byte[] getBinaryMessage(P2PMessage p2PMessage)
        {
            MemoryStream ms = new MemoryStream();

            serializer.Serialize(ms, p2PMessage);
            byte[] send_buffer = ms.ToArray();
            return(send_buffer);
        }
Beispiel #2
0
 static void serializeAndWrite(P2PMessage p2PMessage)
 {
     string path = @"C:\Users\ayanamists\source\repos\P2PDownload\P2PDownload\test";
     var stream = new MemoryStream();
     var serializer = new BinarySerializer();
     serializer.Serialize(stream, p2PMessage);
     WriteToFile($"{path}\\{p2PMessage.type}", stream.ToArray());
 }
Beispiel #3
0
 public static List<P2PMessage> GenFromMS(MemoryStream ms)
 {
     var now_pos = 0;
     List<P2PMessage> ret = new List<P2PMessage>();
     var max_pos = ms.Position;
     ms.Position = 0;
     while (now_pos < max_pos) {
         var buffer_head = new byte[8];
         ms.Read(buffer_head, 0, 8);
         var length = BitConverter.ToInt32(buffer_head, 4);
         var type_value = BitConverter.ToInt32(buffer_head);
         var buffer_tail = new byte[length];
         ms.Read(buffer_tail, 0, length);
         var now_item = new P2PMessage();
         switch (type_value)
         {
             case 0:
                 now_item = new GetDataMessage(buffer_tail);
                 break;
             case 1:
                 now_item = new GetFileInfoMessage(buffer_tail);
                 break;
             case 2:
                 now_item = new GetBlockInfoMessage(buffer_tail);
                 break;
             case 3:
                 now_item =  new DataMessage(buffer_tail);
                 break;
             case 4:
                 now_item = new ErrorMessage(buffer_tail);
                 break;
             case 5:
                 now_item =  new FileInfoMessage(buffer_tail);
                 break;
             case 6:
                 now_item = new BlockInfoMessage(buffer_tail);
                 break;
             case 7:
                 now_item = new OKMessage(buffer_tail);
                 break;
             case 8:
                 now_item = new CloseMessage();
                 break;
             case 9:
                 now_item = new AliveMessage();
                 break;
             default:
                 throw new System.Exception("not allow");
         }
         now_item.type = (P2PMessageType)type_value;
         ret.Add(now_item);
         now_pos += 8 + length;
     }
     Debug.Assert(now_pos == max_pos);
     return ret;
 }
Beispiel #4
0
 static void TestParse(P2PMessage p2PMessage)
 {
     string path = @"C:\Users\ayanamists\source\repos\P2PDownload\P2PDownload\test";
     var i = ReadFromFile($"{path}\\{p2PMessage.type}");
     var r = P2PMessage.GenFromBuffer(i.Item1, i.Item2);
     var stream = new MemoryStream();
     var serializer = new BinarySerializer();
     serializer.Serialize(stream, p2PMessage);
     WriteToFile($"{path}\\{p2PMessage.type}-2", stream.ToArray());
 }
Beispiel #5
0
        void ReadToBuffer(int maxMessage)
        {
            var s = tcpCilent.GetStream();

            // 调节缓冲区大小,修改此变量
            var buffer_size = 5000;
            var buffer      = new byte[buffer_size];
            var length4Read = -1;
            var count       = 0;
            var size        = 0;

            while (count < maxMessage)
            {
                tcpCilent.ReceiveTimeout = 80;
                try
                {
                    do
                    {
                        if (length4Read == -1)
                        {
                            size        = s.Read(buffer, 0, 8);
                            length4Read = P2PMessage.TryParseHeader(buffer);
                        }
                        else if (length4Read == 0)
                        {
                            count++; length4Read = -1; break;
                        }
                        else
                        {
                            var read_size = (length4Read > buffer_size) ? buffer_size : length4Read;
                            size         = s.Read(buffer, 0, read_size);
                            length4Read -= size;
                        }
                        _logger.Info($"read {size} bytes from socket, length for read is {length4Read}");
                        ms.Write(buffer, 0, size);
                    } while (s.DataAvailable);
                }
                catch (IOException)
                {
                    _logger.Info($"Recive timeout");
                    break;
                }
            }
        }
Beispiel #6
0
 public List <P2PMessage> GetReply(int maxReplyMessage)
 {
     ReadToBuffer(maxReplyMessage);
     return(P2PMessage.GenFromMS(ms));
 }
Beispiel #7
0
 void send(P2PMessage message)
 {
     _logger.Info($"send {message.type}, length {message.length}");
     send(getBinaryMessage(message));
 }
Beispiel #8
0
 static void send(P2PMessage message, TcpClient client)
 {
     _logger.Info($"send {message.type}");
     send(getBinaryMessage(message), client);
 }
Beispiel #9
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;
            }
        }