月度存档: 六月 2017

rust 使用 protobuf

没有技术含量的东西,就是记录一下流水帐。

crate.io 上搜索 protobuf:

https://github.com/stepancheg/rust-protobuf

1、下载 google 的 protoc 解压后添加至环境变量

https://github.com/google/protobuf/releases

2、安装 protoc-gen-rust,可以使用命令:

cargo install protobuf

会安装在 C:\Users\Administrator\.cargo\bin 目录下,同样添加至环境变量。

3、使用protoc生成对应的 rust 原码文件

protoc --rust_out . foo.proto

4、在rust工程中Cargo.toml中的添加protobuf

[dependencies]
protobuf = "1.3.1"

5、添加引用的crate:

extern crate protobuf;

6、测试代码:

extern crate protobuf;
use protobuf::Message;

let mut hello=common::Hello::new();
hello.set_id(4);

let data=protobuf::Message::write_to_bytes(&hello).expect("error");
let data2=hello.write_to_bytes().expect("error");
println!("{:?}",data);
println!("{:?}",data2);

let hello=protobuf::parse_from_bytes::<common::Hello>(&data).expect("error");
println!("{}",hello.get_id());

rust学习第一课

使用 tokio 根据文档写一个收发字符串内容的tcp server.

文档地址:https://tokio.rs/docs/getting-started/simple-server/

#[macro_use]
extern crate log;

extern crate bytes;
extern crate tokio_io;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;
extern crate  byteorder;
extern crate futures;


use std::io;
use std::str;
use std::io::Cursor;
use bytes::{BytesMut,BufMut};
use tokio_io::codec::*;
use byteorder::*;
use tokio_proto::TcpServer;
use tokio_proto::pipeline::ServerProto;
//use tokio_proto::multiplex::ServerProto;
//use tokio_proto::streaming::pipeline::ServerProto;
use tokio_io::*;
use tokio_io::codec::Framed;
use tokio_service::Service;
use futures::{future,Future,BoxFuture};

#[test]
fn hello(){
    info!("hello");

    pub struct MessageCodec;

    impl Decoder for MessageCodec{
        type Item=String;
        type Error=io::Error;
        fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error>{
            println!("decode:{}",buf.len());
            if buf.len()<=4 {
                return Ok(None);
            }


            let len=BigEndian::read_i32(buf.split_to(4).as_ref()) as usize;

            let b=buf.split_to(len);
            let content=str::from_utf8(b.as_ref());
            println!("decode 2:{}",buf.len());
            return Ok( Some( content.unwrap().to_owned()  ));
        }
    }

    impl Encoder for MessageCodec{
        type Item=String;
        type Error=io::Error;
        fn encode(&mut self, item: String, buf: &mut BytesMut)
                  -> Result<(), Self::Error>{
            println!("encode:{}",item);
            buf.put_i32::<BigEndian>(item.len() as i32 );
            buf.put_slice(item.into_bytes().as_ref());
            return Ok(());
        }
    }

    pub struct MessageProto;

    impl<T:AsyncRead+AsyncWrite+'static> ServerProto<T> for MessageProto{
        type Request=String;
        type Response=String;
        type Transport=Framed<T,MessageCodec>;

        type BindTransport = Result<Self::Transport,io::Error>;
        fn bind_transport(&self, io: T) -> Self::BindTransport{
            Ok(io.framed(MessageCodec))
        }
    }

    pub struct GameServer;

    impl Service for GameServer{
        /// Requests handled by the service.
        type Request=String;

        /// Responses given by the service.
        type Response=String;

        /// Errors produced by the service.
        type Error=io::Error;

        /// The future response value.
        type Future=BoxFuture<Self::Response,Self::Error  >;

        /// Process the request and return the response asynchronously.
        fn call(&self, req: Self::Request) -> Self::Future{
            println!("receive:{}",req);

            return future::ok(req.chars().rev().collect()).boxed();
        }
    }

    let addr="0.0.0.0:9999".parse().unwrap();
    let server=TcpServer::new(MessageProto,addr);

    println!("start running");
    server.serve(|| Ok(GameServer));

    println!("hello test");
}

第一次基础上算正规的边看文档,边写,边理解语法,边google。

过程中掌握以下知识点:

1、类型转换
i32 转为 u32
a as u32
2、从 [u8] 中读取一个基础类型
BigEndian::read_i32(buf)
3、byte[] 转为字符串
       str::from_utf8([u8])
4、字符串转为bytes
str.into_bytes()
5、slice目前ide无法做到智能语法提示。
       需要自己来处理。
6、bytes取一个slice再转为byte[]
       buf[a..b].as_ref()

下一步就是自己用tcpstream去连上。