J'ai posté ce que j'ai fait pendant que j'étais disciple, je vais donc l'écrire ici aussi!
En réponse à la requête http envoyée par le navigateur (client), le contenu de la requête est renvoyé tel qu'il est dans la réponse http! C'est le serveur d'écho.
(Renvoie généralement les fichiers html et les images ici)
Par conséquent, le but est d'afficher une chaîne de caractères telle que "GET / ~~" (instruction de requête ←) sur le navigateur.
httpserver.
import java.net.ServerSocket
import java.net.Socket
import java.io
import java.io.InputStream
import java.nio.charset.StandardCharsets
object HTTPServer {
def main(args: Array[String]): Unit = {
println("Hello HTTP Server!Strat----->")
//Créez un socket serveur et liez le numéro de port
val serverSocket = new ServerSocket(8000)
println("Serving HTTP on localhost port 8000 ...")
while (true) {
//Le socket du serveur continue d'accepter et d'attendre
val socket = serverSocket.accept()
//input--Lire la requête http
val input = socket.getInputStream
def readUntilEnd(is: InputStream, acc: List[Int] = Nil):String ={
is.read :: acc match {
case x if x.take(4) == List(10,13,10,13) => x.reverse.map(_.toChar).mkString //10,13 est un saut de ligne
case x => readUntilEnd(is, x)
}
}
//output--Renvoyer la demande http
val output = socket.getOutputStream
val CRLF = "\r\n"
val responseBody = readUntilEnd(input)
val responseBodySize = responseBody.length
val responseText = "HTTP/1.1 200 OK" + CRLF +
"Content-Length: " + responseBodySize + CRLF +
"Content-Type: text/plain" + CRLF +
CRLF +
responseBody
output.write(responseText.getBytes(StandardCharsets.UTF_8))
//Fermer la prise
input.close()
output.close()
}
serverSocket.close()
}
}
}
Fondamentalement, si je pouvais trouver une méthode qui ferait ce que je voulais faire d'ici, je sentais qu'elle serait en voie d'achèvement. Et si vous comprenez le concept de cette communication, la signification de la prise et son fonctionnement, vous pouvez lire le code.
text val input = socket.getInputStream
Lorsque vous créez un flux d'entrée avec, les informations (requête http) passent par le tunnel.
J'ai créé une méthode readUntilEnd qui la lit caractère par caractère et la renvoie finalement sous la forme d'une chaîne de caractères unique de type String.
text def readUntilEnd(is: InputStream, acc: List[Int] = Nil):String ={ is.read :: acc match { case x if x.take (4) == List (10,13,10,13) => x.reverse.map (_.toChar) .mkString // 10,13 est un saut de ligne case x => readUntilEnd(is, x) } }
Ce qui est fait dans la correspondance de modèle ici, c'est que si deux sauts de ligne sont envoyés à la fin de l'instruction de requête http, c'est une branche conditionnelle qui arrête la récupération.
Étant donné que chaque caractère entre dans la liste en tant que type Byte, à la fin, retournez-le (inverser) pour en faire un caractère et utilisez mkString pour le presser en une chaîne de caractères de la liste.
De même, créez un flux de sortie et transmettez les informations selon le modèle de réponse http. Vous n'êtes pas obligé d'avoir tous les en-têtes ici, juste ceux dont vous avez besoin.
Mettez les éléments nécessaires dans le corps de la réponse en variables une par une dans le type String, convertissez-les en type Byte à la fois avec responseText, et appliquez la méthode d'écriture au socket, et elle sera envoyée comme réponse http!
Fermez enfin la prise.
Cela semble assez puissant, mais le serveur http le fait.
Je pense encore une fois que tout n'est pas manipulé par magie en un instant. Lol
Recommended Posts