在 Akka Stream 中拒绝来自非本地主机的 TCP 请求
Reject TCP request from not localhost in 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()
}
}
}
在您的服务器代码中,您正在绑定到 127.0.0.1
的环回地址。该地址是唯一的本地地址,因此无法从该机器外部连接。如果您希望能够远程连接,那么在您的服务器代码中,对 Tcp().bind
的调用将需要机器 运行 服务器的实际 ip,而不是环回。此外,正如@sainaen 所建议的,您可以在服务器代码中绑定到 0.0.0.0
以使其绑定到所有可用的网络接口,而不是选择一个显式的 ip 来绑定。
我是 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()
}
}
}
在您的服务器代码中,您正在绑定到 127.0.0.1
的环回地址。该地址是唯一的本地地址,因此无法从该机器外部连接。如果您希望能够远程连接,那么在您的服务器代码中,对 Tcp().bind
的调用将需要机器 运行 服务器的实际 ip,而不是环回。此外,正如@sainaen 所建议的,您可以在服务器代码中绑定到 0.0.0.0
以使其绑定到所有可用的网络接口,而不是选择一个显式的 ip 来绑定。