I made an eco server with scala

I posted what I made while I was a disciple, so I will write it here as well!

What is an echo server?

In response to the http request sent from the browser (client), the content of the request is returned as it is with the http response! That is the echo server.

(Usually returns html files and images here)

Therefore, the goal is to display a character string such as "GET / ~~" (← request statement) on the browser.

The outline is like this

  1. Import usable java packages (link below)
  2. Generate a server socket
  3. Write the code in the while statement so that the server socket keeps accepting
  4. Create an input stream and read the http request
  5. Create an output stream and send back an http request statement
  6. Close the socket

Implementation code introduction

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----->")
       //Create a server socket and bind the port number
       val serverSocket = new ServerSocket(8000)
       println("Serving HTTP on localhost port 8000 ...")
        while (true) {
          //Server socket continues to accept and wait
          val socket = serverSocket.accept()

         //input--Read http request
         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 is a line break
             case x                                   => readUntilEnd(is, x)
           }
         }
   
         //output--Send back http request
         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))
   
         //Close socket
         input.close()
          output.close()
        }
      serverSocket.close()
      }
    }
  }

Basically, if I could find a method that would do what I wanted to do from here, I felt that it would be nearing completion. And if you understand the concept of this communication, the significance of the socket, and how it works, you can read the code.

input About the input stream

text val input = socket.getInputStream

When you create an input stream with, information (http requests) will come through the tunnel.

I created a readUntilEnd method that reads it character by character and finally returns it as a single string of 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 is a line break case x => readUntilEnd(is, x) } }

What is done in the pattern matching here is that if two line breaks are sent at the end of the http request statement, it is a conditional branch that stops recursion.

Since each character enters the list as a Byte type, at the end, turn it over (reverse) to make it a character, and use mkString to squeeze it into one character string from the list.

output About the output stream

Similarly, create an output stream and pass the information according to the http response template. You don't have to have all the headers here, just the ones you need.

Put the necessary items in the response body into variables one by one in String type, convert them to Byte type at once with responseText, and apply the write method to the socket, and it will be sent as an http response!

Finally close the socket.

It feels pretty powerful, but the http server does this.

I think again that not everything is magically manipulated in an instant. Lol

Recommended Posts

I made an eco server with scala
I made an iPhone Theremin with Vision framework + AudioKit
I made an Android application that GETs with HTTP
I made the server side of an online card game ①
I made a server side of an online card game ⑤
I made a server side of an online card game ③
I want to push an app made with Rails 6 to GitHub
I made an adapter for communication class with Retrofit2 + Rx2
I made a server side of an online card game ⑥
I made a server side of an online card game ④
I made a server side of an online card game ②
I made an annotation in Java.
Run an application made with Java8 with Java6
Stupid mistake I made when running nginx server with Docker Compose
I made a risky die with Ruby
I made a rock-paper-scissors app with kotlin
I made a rock-paper-scissors app with android
CentOS8 doesn't have unar binaries so I made an alternative with bash
I made an app to scribble with PencilKit on a PDF file
I made StringUtils.isBlank
04. I made a front end with SpringBoot + Thymeleaf
I made a mosaic art with Pokemon images
I made an app for myself! (Reading management app)
I made a gender selection column with enum
I made blackjack with Ruby (I tried using minitest)
I made an Android app for MiRm service
I made an API client for Nature Remo
Run an application made with Go on Heroku
I made a LINE bot with Rails + heroku
I touched Scala
I made a portfolio with Ruby On Rails
Try running an app made with Quarkus on Heroku
Create an HTTPS file server for development with ring-jetty-adapter
How can I efficiently fill an array with values?
[Ruby] I made a crawler with anemone and nokogiri.
I made a Restful server and client in Spring.
When I bcrypt with node + docker, I got an error
I created an api domain with Spring Framework. Part 1
I struggled with pip install on an M1 Mac
I played with Refinements
I touched Scala ~ [Class] ~
I tried to build an API server with Go (Echo) x MySQL x Docker x Clean Architecture
I touched Scala ~ [Object] ~
I touched Scala ~ [Trait] ~
I tried to make an introduction to PHP + MySQL with Docker
I made a development environment with rails6 + docker + postgreSQL + Materialize.
parquet-tools gives java.lang.ExceptionInInitializerError, so I made it work with java8
I made a plugin to execute jextract with Gradle task
I updated my own blackjack made with Ruby for my portfolio
I made a mod that instantly calls a vehicle with Minecraft
I got an InvalidUseOfMatchersException when using any with JUnit Mock
I tried to link chat with Minecraft server with Discord API
I want to manually send an authorization email with Devise