使用 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去连上。
0 条评论。