2023-09-21 17:10:27 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"os"
|
|
|
|
"fmt"
|
2023-09-22 03:20:44 +00:00
|
|
|
"bufio"
|
|
|
|
"encoding/json"
|
|
|
|
"math/big"
|
|
|
|
"math"
|
2023-09-21 17:10:27 +00:00
|
|
|
)
|
|
|
|
|
2023-09-22 03:20:44 +00:00
|
|
|
type PrimeRequest struct {
|
|
|
|
Method string
|
|
|
|
Number *float64
|
|
|
|
}
|
|
|
|
|
|
|
|
type PrimeResponse struct {
|
|
|
|
Method string `json:"method"`
|
|
|
|
Prime bool `json:"prime"`
|
|
|
|
}
|
|
|
|
|
2023-09-21 17:10:27 +00:00
|
|
|
type PrimeServer struct {
|
|
|
|
port uint16
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPrimeServer(port uint16) *PrimeServer {
|
|
|
|
return &PrimeServer{port}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *PrimeServer) Run() {
|
|
|
|
addr := fmt.Sprintf("0.0.0.0:%d", s.port)
|
|
|
|
server, err := net.Listen("tcp", addr)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error listening:", err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
defer server.Close()
|
|
|
|
fmt.Println("PrimeServer waiting for client...")
|
|
|
|
for {
|
|
|
|
connection, err := server.Accept()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error accepting: ", err.Error())
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
fmt.Println("client connected")
|
|
|
|
go s.processClient(connection)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-22 03:20:44 +00:00
|
|
|
func (s *PrimeServer) processClient(con net.Conn) {
|
|
|
|
var err error
|
|
|
|
scanner := bufio.NewScanner(con)
|
|
|
|
for scanner.Scan() {
|
|
|
|
data := scanner.Bytes()
|
|
|
|
fmt.Printf("Received %d bytes\n", len(data))
|
|
|
|
err = s.processRequest(data, con)
|
|
|
|
if err != nil {
|
2023-09-21 17:10:27 +00:00
|
|
|
break
|
2023-09-22 03:20:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if scanner.Err() != nil {
|
|
|
|
err = scanner.Err()
|
|
|
|
}
|
|
|
|
if err != nil { con.Write([]byte("malformed"))
|
|
|
|
fmt.Println(err)
|
2023-09-21 17:10:27 +00:00
|
|
|
}
|
2023-09-22 03:20:44 +00:00
|
|
|
fmt.Println("close")
|
|
|
|
con.Close()
|
|
|
|
}
|
|
|
|
func (s *PrimeServer) processRequest(data []byte, con net.Conn) error {
|
|
|
|
var q PrimeRequest
|
|
|
|
var r PrimeResponse
|
|
|
|
err := json.Unmarshal(data, &q)
|
|
|
|
fmt.Println(string(data))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if q.Method != "isPrime" {
|
|
|
|
return fmt.Errorf("wrong method: %s", q.Method)
|
|
|
|
}
|
|
|
|
if q.Number == nil {
|
|
|
|
return fmt.Errorf("no number")
|
|
|
|
}
|
|
|
|
r.Method = q.Method
|
|
|
|
r.Prime = isPrime(*q.Number)
|
|
|
|
result, err := json.Marshal(r)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fmt.Println(string(result))
|
|
|
|
_, err = con.Write(result)
|
|
|
|
_, err = con.Write([]byte("\n"))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func isPrime(number float64) bool {
|
|
|
|
if math.Mod(number, 1.0) != 0 {return false}
|
|
|
|
return big.NewInt(int64(number)).ProbablyPrime(0)
|
2023-09-21 17:10:27 +00:00
|
|
|
}
|