Construyendo un mejor cliente de BitTorrent en marcha

Cuando se trata de protocolos de intercambio de archivos entre pares, BitTorrent es probablemente uno de los más conocidos. Requiere que un cliente que implemente el programa y un rastreador enumere los archivos disponibles para transferir y que encuentre usuarios pares para transferir esos archivos. Desarrollado en 2001, BitTorrent ha adquirido desde entonces más de un cuarto de millón de usuarios según algunas estimaciones.

Mientras que la mayoría de los usuarios eligen usar clientes existentes, [Jesse Li] quería construir uno desde cero en Go , un lenguaje de programación comúnmente usado por sus características de concurrencia incorporadas y su simplicidad comparado con C.

Cliente-servidor versus arquitectura peer-to-peer

El primer paso para un cliente es encontrar compañeros de los que descargar archivos. Los trackers, servidores web que funcionan sobre HTTP, sirven como ubicaciones centralizadas para introducir los pares entre sí. Debido a la centralización, los servidores corren el riesgo de ser descubiertos y apagados si facilitan el intercambio de contenido ilegal. Por lo tanto, hacer que el descubrimiento de pares sea un proceso distribuido es una necesidad para evitar que los trackers sigan los pasos de los ya desaparecidos TorrentSpy, Popcorn Time y KickassTorrents.

El cliente comienza leyendo un archivo .torrent, que describe el contenido del archivo deseado y cómo conectarse a un tracker. La información del archivo incluye la URL del rastreador, la hora de creación y los hashes SHA-1 de cada pieza, o un trozo del archivo. Un archivo puede estar compuesto de miles de piezas – el cliente necesitará descargar las piezas de sus pares, comprobar los hashes contra el archivo torrent, y finalmente ensamblar las piezas para finalmente recuperar el archivo. Para la implementación, [Jesse] eligió mantener las estructuras en el programa Go razonablemente planas, separando las estructuras de la aplicación de las estructuras de serialización. Las piezas también se separan en rebanadas de hashes para acceder más fácilmente a los hashes individuales.

El campo de bits explicado como una tarjeta de fidelización de una cafetería.

A continuación, una petición GET a una URL “anunciada” en el archivo torrent anuncia la presencia del cliente a sus pares y recupera una respuesta del tracker con la lista de pares. Para empezar a descargar piezas, el cliente inicia una conexión TCP con un par, completa un apretón de manos bidireccional de BitTorrent e intercambia mensajes para descargar piezas.

Una estructura de datos interesante que se intercambia en los mensajes es un campo de bits, que actúa como una matriz de bytes que comprueba qué piezas tiene un par. Los bits se voltean cuando el estado de su respectiva pieza cambia, actuando de alguna manera como una tarjeta de lealtad con sellos.

Aunque hablar con un compañero puede ser sencillo, manejar la concurrencia de hablar con varios compañeros a la vez requiere resolver un problema clásicamente difícil. [Jesse] implementa esto en Go usando canales como colas seguras de hilos, configurando dos canales para asignar el trabajo y recoger las piezas descargadas. Las peticiones son posteriormente canalizadas para incrementar el rendimiento ya que los viajes de ida y vuelta a la red son costosos y el envío de bloques individualmente ineficiente.

La implementación completa es disponible en GitHub , y es lo suficientemente fácil de usar como un cliente alternativo o como un recorrido si prefieres construir el tuyo propio.

 

Deja un comentario