简体   繁体   中英

Reject TCP request from not localhost in Akka Stream

I'm a learner of Akka Stream. I made a simple file server via TCP and a simple file receiver. When both the server and receiver are in the same host, both work well. But the receiver can't access the server when the receiver is in different host from the server's host. So my question is why the receiver in different host from the server can't access the server .

For example, if I run the server in 192.168.1.20, the receiver in 192.168.1.20 can access the server, but the receiver in 192.168.11.22 can't access the server.

I confirmed that the port is open. I made a simple system which uses the same port, and I could access the port by using telnet command.

The source code is here

Server.scala (file server)

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 (file receiver)

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()
    }
  }
}

In your server code, you are binding to the loopback address of 127.0.0.1 . This address is a local only address and therefore cannot be connected to from outside of that machine. If you want to be able to connect remotely then in your server code, the call to Tcp().bind will need the actual ip of the machine running the server and not the loopback. Also, as suggested by @sainaen, you can bind to 0.0.0.0 in the server code to have it bind to all available network interfaces instead of picking an explicit ip to bind to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM