public static PeerMessage CreateFromBytes(byte[] buffer, int offset, int count) { if(buffer.Length < offset+count) throw new ArgumentException("Buffer is too small."); PeerMessage message; int length = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(buffer, offset)); byte firstByte = buffer[offset]; if (firstByte == 0 && count == 1) return new KeepAliveMessage(); if (firstByte == 19 && count == 68) { message = new HandshakeMessage(); message.FromBytes(buffer, offset, count); return message; } byte id = buffer[offset + 4]; if (!messages.ContainsKey(id)) throw new TorrentException("Unknown message."); message = messages[id](); message.FromBytes(buffer, offset, count); return message; }
protected TorrentMode(BlockManager manager, BlockStrategist strategist, TorrentData metadata, TransferMonitor monitor) { //инициализация на обект за следене на пренесените данни Monitor = monitor; //обект за управляване на записа на парчета върху файловата система BlockManager = manager; //обект за управление на заявките на парчета към пиърите BlockStrategist = strategist; //обект, съдържаш метаданните на торента Metadata = metadata; //съобщение за здрависване, което се използва от този TorrentMode DefaultHandshake = new HandshakeMessage(Global.Instance.PeerId, new byte[8], Metadata.InfoHash, "BitTorrent protocol"); //конкурентен речник за съхранение на състоянието на активните пиъри Peers = new ConcurrentDictionary<string, PeerState>(); //прикачане на събитието за изключения на BlockManager-а manager.RaisedException += (s, e) => HandleException(e.Value); //инициализация на теймера за изпращане на KeepAlive съобщения KeepAliveTimer = new Timer(SendKeepAlives); }
protected virtual void SendHandshake(PeerState peer, HandshakeMessage handshake) { if (Stopping) return; MessageIO.SendMessage(peer.Socket, handshake, peer, HandshakeSent); }
protected virtual void HandleHandshake(HandshakeMessage handshake, PeerState peer) { peer.ReceivedHandshake = true; peer.ID = handshake.PeerID; if (!peer.SentHandshake) SendHandshake(peer, DefaultHandshake); else AddPeer(peer); }