Pug_coder

client

Sep 10th, 2021
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.92 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "encoding/base64"
  5.     "encoding/json"
  6.     "flag"
  7.     "fmt"
  8.     "github.com/skorobogatov/input"
  9.     "io/ioutil"
  10.     "net"
  11.     _ "image"
  12. )
  13.  
  14. import "proto"
  15.  
  16. // interact - функция, содержащая цикл взаимодействия с сервером.
  17. func interact(conn *net.TCPConn) {
  18.     defer conn.Close()
  19.     encoder, decoder := json.NewEncoder(conn), json.NewDecoder(conn)
  20.     for {
  21.         // Чтение команды из стандартного потока ввода
  22.         fmt.Printf("command = ")
  23.         command := input.Gets()
  24.  
  25.         // Отправка запроса.
  26.         switch command {
  27.         case "loadImage":
  28.             fmt.Print("Image path = ")
  29.             path := input.Gets()
  30.             reader, err := ioutil.ReadFile(path)
  31.              if err != nil {
  32.                 fmt.Print("Image not found")
  33.                 continue
  34.              }
  35.             encoded := base64.StdEncoding.EncodeToString(reader)
  36.             send_request(encoder, "loadImage", &proto.Image{encoded})
  37.         case "quit":
  38.             send_request(encoder, "quit", nil)
  39.             return
  40.         case "getSize":
  41.             send_request(encoder, "getSize", nil)
  42.         case "getColor":
  43.             fmt.Print("x = ")
  44.             var x, y int
  45.             fmt.Scan(&x)
  46.             fmt.Print("y = ")
  47.             fmt.Scan(&y)
  48.             send_request(encoder, "getColor", &proto.Coordinates{x,y})
  49.         default:
  50.             fmt.Printf("error: unknown command\n")
  51.             continue
  52.         }
  53.  
  54.         // Получение ответа.
  55.         var resp proto.Response
  56.         if err := decoder.Decode(&resp); err != nil {
  57.             fmt.Printf("error: %v\n", err)
  58.             break
  59.         }
  60.  
  61.         // Вывод ответа в стандартный поток вывода.
  62.         switch resp.Status {
  63.         case "ok":
  64.             fmt.Printf("ok\n")
  65.         case "failed":
  66.             if resp.Data == nil {
  67.                 fmt.Printf("error: data field is absent in response\n")
  68.             } else {
  69.                 var errorMsg string
  70.                 if err := json.Unmarshal(*resp.Data, &errorMsg); err != nil {
  71.                     fmt.Printf("error: malformed data field in response\n")
  72.                 } else {
  73.                     fmt.Printf("failed: %s\n", errorMsg)
  74.                 }
  75.             }
  76.         case "getSizeResult":
  77.             if resp.Data == nil {
  78.                 fmt.Printf("error: data field is absent in response\n")
  79.             } else {
  80.                 var size proto.ImageSize
  81.                 if err := json.Unmarshal(*resp.Data, &size); err != nil {
  82.                     fmt.Printf("error: malformed data field in response\n")
  83.                 } else {
  84.                     fmt.Printf("result: %dx%d\n", size.Weight, size.Height)
  85.                 }
  86.             }
  87.         case "getColorResult":
  88.             if resp.Data == nil {
  89.                 fmt.Printf("error: data field is absent in response\n")
  90.             } else {
  91.                 var color proto.ImageColor
  92.                 if err := json.Unmarshal(*resp.Data, &color); err != nil {
  93.                     fmt.Printf("error: malformed data field in response\n")
  94.                 } else {
  95.                     fmt.Printf("R: %d G: %d B: %d A: %d\n", color.R / 255, color.G / 255, color.B /255, color.A / 255)
  96.                 }
  97.             }
  98.         default:
  99.             fmt.Printf("error: server reports unknown status %q\n", resp.Status)
  100.         }
  101.     }
  102. }
  103.  
  104. // send_request - вспомогательная функция для передачи запроса с указанной командой
  105. // и данными. Данные могут быть пустыми (data == nil).
  106. func send_request(encoder *json.Encoder, command string, data interface{}) {
  107.     var raw json.RawMessage
  108.     raw, _ = json.Marshal(data)
  109.     encoder.Encode(&proto.Request{command, &raw})
  110. }
  111.  
  112. func main() {
  113.     // Работа с командной строкой, в которой может указываться необязательный ключ -addr.
  114.     var addrStr string
  115.     flag.StringVar(&addrStr, "addr", "127.0.0.1:6000", "specify ip address and port")
  116.     flag.Parse()
  117.  
  118.     // Разбор адреса, установка соединения с сервером и
  119.     // запуск цикла взаимодействия с сервером.
  120.     if addr, err := net.ResolveTCPAddr("tcp", addrStr); err != nil {
  121.         fmt.Printf("error: %v\n", err)
  122.     } else if conn, err := net.DialTCP("tcp", nil, addr); err != nil {
  123.         fmt.Printf("error: %v\n", err)
  124.     } else {
  125.         interact(conn)
  126.     }
  127. }
  128.  
Add Comment
Please, Sign In to add comment