009 rust network programming, serialization and deserialization

Time:2021-3-3

introduce

Serde crite is the core of serde ecology. serde_ Derive crite provides the necessary tools to derive serialize and deserialize using process macros. However, serde only provides the framework of serialization and deserialization, and the specific operation also depends on specific packages, such as serde_ JSON and serde_ Yaml et al.
Here are two examples.

Serialization and serialization examples

Simple example 1

  • Create project

    cargo new use_ser
  • modify Cargo.toml Files, adding dependencies

    [dependencies]
    serde = { version = "1.0.106", features = ["derive"] }
    serde_json = "1.0.52"
    serde_yaml = "0.8.11"
  • Source code:

    use serde::{Serialize, Deserialize};
    #[derive(Serialize, Deserialize, Debug)]
    struct ServerConfig {
      workers: u64,
      ignore: bool,
      auth_server: Option<String>,
    }
    fn main() {
      let config = ServerConfig {
          workers: 100,
          ignore: false,
          auth_server: Some(String::from("auth.server.io")),
      };
      {
          println!("To and from Json");
          let serialized = serde_json::to_string(&config).unwrap();
          println!("serialized: {}", serialized);
          println!("");
    
          let deserialized: ServerConfig = serde_json::from_str(&serialized).unwrap();
          println!("deserialized: {:#?}", deserialized);
      }
    
      println!("");
      println!("");
    
      {
          println!("To and from Yaml");
          let serialized = serde_yaml::to_string(&config).unwrap();
          println!("serialized: {}", serialized);
    
          println!("");
          let deserialized: ServerConfig = serde_yaml::from_str(&serialized).unwrap();
          println!("deserialized: {:#?}", deserialized);
      }
    }
  • Running results

    To and from Json
    serialized: {"workers":100,"ignore":false,"auth_server":"auth.server.io"}
    deserialized: ServerConfig {
      workers: 100,
      ignore: false,
      auth_server: Some(
          "auth.server.io",
      ),
    }
    To and from Yaml
    serialized: ---
    workers: 100
    ignore: false
    auth_server: auth.server.io
    deserialized: ServerConfig {
      workers: 100,
      ignore: false,
      auth_server: Some(
          "auth.server.io",
      ),
    }

    Network examples

    Server side

  • Create project

    cargo new server
  • modify Cargo.toml Files, adding dependencies

    [dependencies]
    serde = { version = "1.0.106", features = ["derive"] }
    serde_json = "1.0.52"
  • Source code

    use serde::{Deserialize, Serialize};
    use serde_json;
    use std::io::{self, prelude::*, BufReader, Write};
    use std::net::{TcpListener, TcpStream};
    use std::{str, thread};
    #[derive(Debug, Serialize, Deserialize)]
    struct Point3D {
      x: u32,
      y: u32,
      z: u32,
    }
    fn handle_client(stream: TcpStream) -> io::Result<()> {
      println!("Incoming connection from: {}", stream.peer_addr()?);
      let mut data = Vec::new();
      let mut stream = BufReader::new(stream);
    
      loop {
          data.clear();
    
          let bytes_read = stream.read_until(b'\n', &mut data)?;
          if bytes_read == 0 {
              return Ok(());
          }
          let input: Point3D = serde_json::from_slice(&data)?;
          let value = input.x.pow(2) + input.y.pow(2) + input.z.pow(2);
    
          stream.get_mut().write(&(serde_json::to_vec(&(f64::from(value).sqrt()))?))?;
          stream.get_mut().write(&("\n".as_bytes()))?;
          stream.get_mut().flush()?;
    
          // write!(stream.get_mut(), "{}", f64::from(value).sqrt())?;
          // write!(stream.get_mut(), "{}", "\n")?;
      }
    }
    fn main() -> io::Result<()> {
      let listener = TcpListener::bind("0.0.0.0:8080")?;
      for stream in listener.incoming() {
          match stream {
              Err(e) => eprintln!("failed: {}", e),
              Ok(stream) => {
                  thread::spawn(move || {
                      handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
                  });
              }
          }
      }
    
      Ok(())
    }

    Client side

  • Create project

    cargo new client
  • modify Cargo.toml Files, adding dependencies

    [dependencies]
    serde = { version = "1.0.106", features = ["derive"] }
    serde_json = "1.0.52"
  • Source code

    use serde::{Deserialize, Serialize};
    use serde_json;
    use std::io::{self, prelude::*, BufReader, Write};
    use std::net::TcpStream;
    use std::str;
    #[derive(Debug, Serialize, Deserialize)]
    struct Point3D {
      x: u32,
      y: u32,
      z: u32,
    }
    fn main() -> io::Result<()> {
      let mut stream = TcpStream::connect("127.0.0.1:8080")?;
    
      println!("Please provide a 3D point as three comma separated integers");
      loop {
          let mut input = String::new();
          let mut buffer: Vec<u8> = Vec::new();
          io::stdin()
              .read_line(&mut input)
              .expect("Failed to read from stdin");
          let parts: Vec<&str> = input.trim_matches('\n').split(',').collect();
          let point = Point3D {
              x: parts[0].parse().unwrap(),
              y: parts[1].parse().unwrap(),
              z: parts[2].parse().unwrap(),
          };
    
          stream
              .write_all(serde_json::to_string(&point).unwrap().as_bytes())
              .expect("Failed to write to server");
          stream.write_all(b"\n").expect("Failed to write to server");
    
          let mut reader = BufReader::new(&stream);
          reader
              .read_until(b'\n', &mut buffer)
              .expect("Could not read into buffer");
          let input = str::from_utf8(&buffer).expect("Could not write buffer as string");
          if input == "" {
              eprintln!("Empty response from server");
          }
          print!("Response from server {}", input);
      }
    }

    Operation mode

  • Start with server

    cargo run server
  • Start client

    cargo run client

    The clients are as follows:

    Please provide a 3D point as three comma separated integers
    1,2,3 // enter 1,2,3
    Response from server 3.7416573867739413 // returns the calculation result

This work adoptsCC agreementReprint must indicate the author and the link of this article

Linghu Yichong

Recommended Today

Third party calls wechat payment interface

Step one: preparation 1. Wechat payment interface can only be called if the developer qualification has been authenticated on wechat open platform, so the first thing is to authenticate. It’s very simple, but wechat will charge 300 yuan for audit 2. Set payment directory Login wechat payment merchant platform( pay.weixin.qq . com) — > Product […]