使用Akka的UDP跟踪器协议

时间:2016-11-17 04:54:02

标签: scala udp akka bittorrent

我正在尝试使用Akka IO模块实现BitTorrent Udp Tracker协议。协议的第一步是向跟踪器发送16字节有效负载,如上所述here。我无法收到数据作为回报。非常感谢任何帮助。

package tracker

import java.net.InetSocketAddress
import java.nio.ByteOrder

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.io.Udp.Event
import akka.io.{IO, Udp}
import akka.util.ByteString

object udpTest extends App {

  val system = ActorSystem("UDPTest")

  val (listenPort, sendPort) = (6960, 80)
  val url = "udp://tracker.openbittorrent.com"
  val listenerActor1: ActorRef = system.actorOf(Props
  (new Listener(listenPort, sendPort, url)))

  implicit val networkOrder = ByteOrder.BIG_ENDIAN
  //  0x41727101980 = 4497486125440
  val payLoad: ByteString = ByteString.newBuilder.putLong("4497486125440".toLong)
    .putInt(0).putInt(scala.util.Random.nextInt).result

  Thread.sleep(1000)
  listenerActor1 ! payLoad

}

object DataSent extends Event

class Listener(listenPort: Int, sendPort: Int, url: String) extends Actor {

  IO(Udp)(context.system) ! Udp.Bind(self,
    new InetSocketAddress("localhost", listenPort))

  def receive = {
    case Udp.Bound(local) =>
      println(s"Listening on $listenPort")
      context.become(ready(sender()))
  }

  def ready(socket: ActorRef): Receive = {
    case Udp.Received(data, remote) =>
      println(s"Response Received ${data.map(b => "%02x" format b).mkString}")
    case payLoad: ByteString =>
      println(s"Sending payload ${payLoad.map(b => "%02x" format b).mkString}")
      socket ! Udp.Send(payLoad, new InetSocketAddress(url, sendPort), DataSent)
    case Udp.Unbind => socket ! Udp.Unbind
    case Udp.Unbound => context.stop(self)
    case DataSent => println("Data is sent")
  }
}

0 个答案:

没有答案