Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 套接字编程练习挂起?_Java_Scala - Fatal编程技术网

Java 套接字编程练习挂起?

Java 套接字编程练习挂起?,java,scala,Java,Scala,我创建了一个非常简单的HTTP代理服务器和后端服务器,可以生成简单的请求 代理服务器 package ch2.networking import java.io.{BufferedReader, InputStreamReader} import java.net.{ServerSocket, Socket} class ProxyServer(address: String, port: Int, proxyPort: Int) { val proxySocket = new Serv

我创建了一个非常简单的HTTP代理服务器和后端服务器,可以生成简单的请求

代理服务器

package ch2.networking

import java.io.{BufferedReader, InputStreamReader}
import java.net.{ServerSocket, Socket}

class ProxyServer(address: String, port: Int, proxyPort: Int) {
  val proxySocket = new ServerSocket(proxyPort)

  while (true) {
    println("Proxy accepting connections...")
    val connectionSocket = proxySocket.accept()
    println(s"Proxy Accepted Connection: $connectionSocket")

    val connectionInputStream = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream))

    val serverSocket = new Socket(address, port)
    val serverInputStream = new BufferedReader(new InputStreamReader(serverSocket.getInputStream))

    val message: String = connectionInputStream.readLine()
    println(s"Proxy server received: $message")
    serverSocket.getOutputStream.write(message.getBytes("UTF-8"))

    val response = serverInputStream.readLine()
    println(s"Proxy server received $response from server")
    connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
  }
}
网络服务器

package ch2.networking

import java.io.{BufferedReader, InputStreamReader}
import java.net.ServerSocket

class Server(port: Int) {
  val socket = new ServerSocket(port)

  while (true) {
    println("Server accepting connections...")
    val connectionSocket = socket.accept()
    println(s"Server Accepted Connection: $connectionSocket")
    val inputStream = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream))
    val request = inputStream.readLine()
    println(s"Received: $request")
    val response =
      """
        |HTTP/1.1 200 OK
        |
        |
        |Yay you win
        |""".stripMargin
    connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
  }
}

代理收到消息,但对web服务器的写入将永远挂起。我做错了什么?

在这种情况下,您只需在编写服务器响应后添加
connectionSocket.close()
,即可使其正常工作。

在这种情况下,您只需在编写服务器响应后添加
connectionSocket.close()
,即可使其正常工作。

以下是一个有效的实现:

import java.io.InputStream
import java.net.{ServerSocket, Socket}

import scala.annotation.tailrec

trait InputReader {
  @tailrec
  final def readRecur(in: InputStream, sb: StringBuilder = new StringBuilder): String = {
    val input = in.read()
    if (input != -1) {
      readRecur(in, sb.append(input.toChar))
    } else sb.toString()
  }
}

class Server(port: Int) extends Thread with InputReader {
  val socket = new ServerSocket(port)
  override def run(): Unit = {
    while (true) {
      println("Server accepting connections...")
      val connectionSocket = socket.accept()
      println(s"Server Accepted Connection: $connectionSocket")

      val in = connectionSocket.getInputStream
      val message = readRecur(in)

      println(s"Received: $message")
      val response =
        """
          |HTTP/1.1 200 OK
          |
          |
          |Yay you win
          |""".stripMargin
      connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
      connectionSocket.shutdownOutput()
    }
  }
}

class ProxyServer(address: String, port: Int, proxyPort: Int)
    extends Thread
    with InputReader {
  val proxySocket = new ServerSocket(proxyPort)

  override def run(): Unit = {
    while (true) {
      println("Proxy accepting connections...")
      val connectionSocket = proxySocket.accept()
      val connectionInputStream = connectionSocket.getInputStream
      println(s"Proxy Accepted Connection: $connectionSocket")

      val serverSocket = new Socket(address, port)
      val serverInputStream = serverSocket.getInputStream

      val message: String = readRecur(connectionInputStream)
      println(s"Proxy server received: $message")
      serverSocket.getOutputStream.write(message.getBytes("UTF-8"))
      serverSocket.shutdownOutput()

      val response = readRecur(serverInputStream)
      println(s"Proxy server received $response from server")
      connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
      connectionSocket.shutdownOutput()
    }
  }
}

object ProxyServer extends InputReader {
  def main(args: Array[String]): Unit = {
    val server = new Server(2222)
    println("starting server")
    server.start()

    val proxyServer = new ProxyServer("0.0.0.0", 2222, 3333)
    println("starting proxy server")
    proxyServer.start()

    // Begin testing
    val proxyServerSocket = new Socket("0.0.0.0", 2222)
    val message: String = "Hello!"
    println(s"Client sending message: $message")
    proxyServerSocket.getOutputStream.write(message.getBytes("UTF-8"))
    proxyServerSocket.shutdownOutput()

    val response = readRecur(proxyServerSocket.getInputStream)
    println(s"Client received: $response")

    server.stop()

  }
}
显然,问题在于读取操作,他们永远不知道什么时候停止期望更多。套接字通信是非常基本的,客户端和服务器必须在协议(类似http)上达成一致,以确保它们都能相互理解


在上面的示例中,我创建了一个非常基本的阅读器,它会一直阅读,直到通信从另一端标记为完成。

下面是一个有效的实现:

import java.io.InputStream
import java.net.{ServerSocket, Socket}

import scala.annotation.tailrec

trait InputReader {
  @tailrec
  final def readRecur(in: InputStream, sb: StringBuilder = new StringBuilder): String = {
    val input = in.read()
    if (input != -1) {
      readRecur(in, sb.append(input.toChar))
    } else sb.toString()
  }
}

class Server(port: Int) extends Thread with InputReader {
  val socket = new ServerSocket(port)
  override def run(): Unit = {
    while (true) {
      println("Server accepting connections...")
      val connectionSocket = socket.accept()
      println(s"Server Accepted Connection: $connectionSocket")

      val in = connectionSocket.getInputStream
      val message = readRecur(in)

      println(s"Received: $message")
      val response =
        """
          |HTTP/1.1 200 OK
          |
          |
          |Yay you win
          |""".stripMargin
      connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
      connectionSocket.shutdownOutput()
    }
  }
}

class ProxyServer(address: String, port: Int, proxyPort: Int)
    extends Thread
    with InputReader {
  val proxySocket = new ServerSocket(proxyPort)

  override def run(): Unit = {
    while (true) {
      println("Proxy accepting connections...")
      val connectionSocket = proxySocket.accept()
      val connectionInputStream = connectionSocket.getInputStream
      println(s"Proxy Accepted Connection: $connectionSocket")

      val serverSocket = new Socket(address, port)
      val serverInputStream = serverSocket.getInputStream

      val message: String = readRecur(connectionInputStream)
      println(s"Proxy server received: $message")
      serverSocket.getOutputStream.write(message.getBytes("UTF-8"))
      serverSocket.shutdownOutput()

      val response = readRecur(serverInputStream)
      println(s"Proxy server received $response from server")
      connectionSocket.getOutputStream.write(response.getBytes("UTF-8"))
      connectionSocket.shutdownOutput()
    }
  }
}

object ProxyServer extends InputReader {
  def main(args: Array[String]): Unit = {
    val server = new Server(2222)
    println("starting server")
    server.start()

    val proxyServer = new ProxyServer("0.0.0.0", 2222, 3333)
    println("starting proxy server")
    proxyServer.start()

    // Begin testing
    val proxyServerSocket = new Socket("0.0.0.0", 2222)
    val message: String = "Hello!"
    println(s"Client sending message: $message")
    proxyServerSocket.getOutputStream.write(message.getBytes("UTF-8"))
    proxyServerSocket.shutdownOutput()

    val response = readRecur(proxyServerSocket.getInputStream)
    println(s"Client received: $response")

    server.stop()

  }
}
显然,问题在于读取操作,他们永远不知道什么时候停止期望更多。套接字通信是非常基本的,客户端和服务器必须在协议(类似http)上达成一致,以确保它们都能相互理解

在上面的示例中,我创建了一个非常基本的阅读器,它会一直阅读,直到从另一端标记完成通信为止