tokio tcp通信

2024-02-12 21:04
文章标签 通信 tcp tokio

本文主要是介绍tokio tcp通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引入crate

tokio = { version = "1.35.1", features = ["full"] }

服务端

use std::time::Duration;
use tokio::{io::{AsyncBufReadExt, AsyncWriteExt},net::{tcp::{OwnedReadHalf, OwnedWriteHalf},TcpListener, TcpStream,},sync::mpsc,
};#[tokio::main]
async fn main() {println!("Begin Start Server...");let server = TcpListener::bind("127.0.0.1:10888").await.unwrap();while let Ok((client_stream, client_addr)) = server.accept().await{println!("accept client: {}", client_addr);tokio::spawn(async move{process_client(client_stream).await;});}
}async fn process_client(client_stream: TcpStream){let (client_reader, client_writer) = client_stream.into_split();let (msg_tx, msg_rx) = mpsc::channel::<String>(100);let mut read_task = tokio::spawn(async move {read_from_client(client_reader, msg_tx).await;});let mut write_task = tokio::spawn(async move{write_to_client(client_writer, msg_rx).await;});if tokio::try_join!(&mut read_task, &mut write_task).is_err() {read_task.abort();write_task.abort();};
}async fn read_from_client(reader: OwnedReadHalf, mst_tx: mpsc::Sender<String>){let mut buf_reader = tokio::io::BufReader::new(reader);let mut buf = String::new();loop{match buf_reader.read_line(&mut buf).await{Err(_e) =>{eprintln!("read from client error");break;}Ok(0) =>{println!("client closed");break;}Ok(n) => {buf.pop(); //去除末尾的回车符let mut content = buf.drain(..).as_str().to_string();println!("read {} bytes from client. content: {}", n, content);tokio::time::sleep(Duration::from_secs(1)).await;content.push('\n');if mst_tx.send(content).await.is_err(){eprintln!("receiver closed");break;}}}}
}async fn write_to_client(writer: OwnedWriteHalf, mut msg_rx: mpsc::Receiver<String>){let mut buf_writer = tokio::io::BufWriter::new(writer);while let Some(mut str) = msg_rx.recv().await{//str.push('\n');if let Err(e) = buf_writer.write_all(str.as_bytes()).await {eprintln!("write to client failed: {}", e);break;}buf_writer.flush().await;print!("write to client: {}", str);}
}

客户端

use std::sync;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{Local, NaiveDateTime};use tokio::{io::{Interest, AsyncBufReadExt, AsyncWriteExt},net::{tcp::{OwnedReadHalf, OwnedWriteHalf},TcpStream,},sync::mpsc,
};#[tokio::main]
async fn main() {let stream = TcpStream::connect("127.0.0.1:10888").await.unwrap();let (reader, writer) = stream.into_split();let mut buf = String::new();//[0u8, 12];let mut buf_reader = tokio::io::BufReader::new(reader);let mut buf_writer = tokio::io::BufWriter::new(writer);loop{let now=Local::now();let formatted=now.format("%Y-%m-%d %H:%M:%S");let content = format!("hello world {}\n", formatted);//buf_writer.write_all(b"hello world\n").await;buf_writer.write_all(content.as_bytes()).await;buf_writer.flush().await;println!("send:{}", content);match buf_reader.read_line(&mut buf).await {Err(_e) =>{eprintln!("read from server error");break;}Ok(n) =>{buf.pop();let content = buf.as_str().to_string();println!("received: {}  {}", n, content);}};}}

客户端、服务端都使用TcpStream的into_split方法获取网络通信读和写实例,进而获取buffer读写对象,通过channel实现线程执行同步。子线程使用tokio::spawn函数启动。

这篇关于tokio tcp通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/703602

相关文章

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理(三次握手、四次挥手) 三次握手(建立TCP连接) 四次挥手(断开连接)  4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答  9.基于字节流 10.异常情况的处理 小结  前言 在前面,我们已经讲解了有关UDP协议的相关知识,但是在传输层,还有

C++编程:ZeroMQ进程间(订阅-发布)通信配置优化

文章目录 0. 概述1. 发布者同步发送(pub)与订阅者异步接收(sub)示例代码可能的副作用: 2. 适度增加缓存和队列示例代码副作用: 3. 动态的IPC通道管理示例代码副作用: 4. 接收消息的超时设置示例代码副作用: 5. 增加I/O线程数量示例代码副作用: 6. 异步消息发送(使用`dontwait`标志)示例代码副作用: 7. 其他可以考虑的优化项7.1 立即发送(ZMQ_IM