在Akka Stream中拒绝来自非localhost的TCP请求

时间:2016-03-21 10:40:44

标签: scala akka akka-stream

我是Akka Stream的学习者。我通过TCP和一个简单的文件接收器创建了一个简单的文件服务器当服务器和接收器都在同一主机中时,两者都运行良好。但是当接收器与服务器主机位于不同的主机时,接收器无法访问服务器。所以我的问题是为什么来自服务器的不同主机中的接收器无法访问服务器

例如,如果我在192.168.1.20中运行服务器,192.168.1.20中的接收器可以访问服务器,但192.168.11.22中的接收器无法访问服务器。

我确认端口已打开。我创建了一个使用相同端口的简单系统,我可以使用telnet命令访问该端口。

源代码在这里

Server.scala(文件服务器)

import java.io.File

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{FileIO, Flow, Keep, Sink, Tcp}

import scala.io.StdIn

/**
  * Created by Jimmy on 2016/03/21.
  */
object Server {
  def main(args: Array[String]) {

    implicit val system = ActorSystem("system")
    implicit val materializer = ActorMaterializer()
    import system.dispatcher

    // choose which file is uploaded
    val filePath: String = if(args.length == 1){
      args(0)
    } else {
      StdIn.readLine("File Path: ")
    }

    val sourceFile = new File(filePath)
    println(sourceFile.exists())


    Tcp().bind("127.0.0.1", 9999) runForeach {connection =>
      println(s"client address: ${connection.remoteAddress}")

      val sendFileFlow = Flow.fromSinkAndSourceMat(Sink.ignore, FileIO.fromFile(sourceFile))(Keep.right)

      connection.handleWith(sendFileFlow).onComplete{r =>
        println(s"result: $r")
      }
    }
    println("server running...")
  }
}

Client.scala(文件接收器)

import java.io.File

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{FileIO, Flow, Keep, Source, Tcp}
import akka.util.ByteString

import scala.io.StdIn

/**
  * Created by Jimmy on 2016/03/21.
  */
object Client {
  def main(args: Array[String]) {

    implicit val system = ActorSystem("system")
    implicit val materializer = ActorMaterializer()
    import system.dispatcher

    // choose a host
    val host: String = if(args.length == 1){
      args(0)
    } else {
      StdIn.readLine("Host: ")
    }

    val port = 9999
    val storageFile = new File("storage-file")

    import java.nio.file.StandardOpenOption._
    val saveFileFlow = Flow.fromSinkAndSourceMat(FileIO.toFile(storageFile, options=Set(CREATE, WRITE)), Source.repeat(ByteString.empty))(Keep.left)

    Tcp().outgoingConnection(host, port).joinMat(saveFileFlow)(Keep.right).run().onComplete{r =>
      println(s"result: $r")
      system.terminate()
    }
  }
}

1 个答案:

答案 0 :(得分:6)

在您的服务器代码中,您绑定到127.0.0.1的环回地址。此地址是仅限本地的地址,因此无法从该计算机的外部连接。如果您希望能够远程连接,那么在您的服务器代码中,对Tcp().bind的调用将需要运行服务器的机器的实际IP而不是环回。此外,正如@sainaen所建议的那样,您可以绑定到服务器代码中的0.0.0.0,以使其绑定到所有可用的网络接口,而不是选择要绑定的显式IP。