Java 套接字编程练习挂起?
我创建了一个非常简单的HTTP代理服务器和后端服务器,可以生成简单的请求 代理服务器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
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)上达成一致,以确保它们都能相互理解
在上面的示例中,我创建了一个非常基本的阅读器,它会一直阅读,直到从另一端标记完成通信为止