TcpClient类异步接收数据

2023-11-01 02:38

本文主要是介绍TcpClient类异步接收数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 构造函数
  • 属性
  • 主要方法
  • 流程
    • TcpClient读取数据过程
      • TcpClient连接
      • TcpClient已经连接上NetworkStream读取
      • NetworkStream已经读取完毕取出数据
    • TcpClient发送数据流程
      • TcpClient线程
      • NetworkStream异步发送线程
  • 实例
    • TcpClient连接
    • NetworkStream异步读取
    • NetworkStream读取处理
    • NetworkStream发送

TcpClient为基于Socket构建的用来进行TCP通信的简单类,主要用于TCP客户端的编写,可以使用同步或者异步。发送接收数据用NetworkStream。很多东西摘录自MSDN

构造函数

名称说明
TcpClient()初始化 TcpClient 类的新实例。
TcpClient(AddressFamily)使用指定的族初始化 TcpClient 类的新实例。
TcpClient(IPEndPoint)初始化 TcpClient 类的新实例,并将其绑定到指定的本地终结点。
TcpClient(String, Int32)初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。

以上是摘自MSDN上的,其中AddressFamily指的是使用指定的协议族,例如IPv4或者IPv6 
如果要指定本地端口,用IPEndPoint来进行绑定。

属性

TcpCient

名称说明
Active获取或设置一个值,该值指示是否已建立连接。
Client获取或设置基础 Socket。
Connected获取一个值,该值指示 TcpClient 的基础 Socket 是否已连接到远程主机。

NetworkStream

名称说明
CanRead获取一个值,该值指示 NetworkStream 是否支持读取
CanWrite获取一个值,该值指示 NetworkStream 是否支持写入

主要方法

TcpClient

名称说明
BeginConnect(IPAddress, Int32, AsyncCallback, Object)开始一个对远程主机连接的异步请求。远程主机由 IPAddress 和端口号 (Int32) 指定。
Close()释放此 TcpClient 实例,并请求关闭基础 TCP 连接。

NetworkStream

名称说明
BeginRead(Byte[], Int32, Int32, AsyncCallback, Object)从 NetworkStream 开始异步读取。
Close()关闭当前流并释放与之关联的所有资源
BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object)开始向流异步写入

流程

TcpClient读取数据过程

TcpClient连接

主线程实例化TcpClient,可绑定本地端口异步连接到目标IP和端口(BeginConnect)结束

TcpClient已经连接上,NetworkStream读取

TcpClient异步连接线程还原TcpClient获取NetworkStreamNetworkStream可读NetworkStream异步读取Buffer异步结束yesno

NetworkStream已经读取完毕,取出数据

NetworkStream异步读取线程还原异步读取Buffer获取Buffer数据下一次异步读取开启异步读取结束

TcpClient发送数据流程

确保TcpClient已经连接的情况下执行

TcpClient线程

TcpClient发送取得NetworkStream获得数据,异步发送BeginWrite发送结束

NetworkStream异步发送线程

NetworkStream异步发送还原NetworkStream结束发送

实例

TcpClient连接

private void TcpButton_Click(object sender, EventArgs e)
{if (TcpButton.Text == "TCP打开"){TcpButton.Text = "TCP关闭";IPEndPoint targetPoint = new IPEndPoint(TcpUdp.VerifyInputIP(IPTextBox.Text), TcpUdp.VerifyInputPort(TcpTargetPortTextBox.Text));int localTcpPort = Int32.Parse(TcpSourcePortTextBox.Text);if (localTcpPort > 0){IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), localTcpPort);tcp = new TcpClient(localEP);}else{tcp = new TcpClient();}tcp.ReceiveTimeout = 10;//异步连接tcp.BeginConnect(IPAddress.Parse(IPTextBox.Text), TcpUdp.VerifyInputPort(TcpTargetPortTextBox.Text), Connected, tcp);}else{TcpButton.Text = "TCP打开";if ((tcp != null) && (tcp.Connected)){ns.Close();tcp.Close();}SetTcpPic(tcp.Connected);TcpIsOpen = tcp.Connected;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

NetworkStream异步读取

private void Connected(IAsyncResult iar)
{tcp = (TcpClient)iar.AsyncState;tcp.EndConnect(iar);//MessageBox.Show("connected");SetTcpPic(tcp.Connected);TcpIsOpen = tcp.Connected;if ((tcp != null) && (tcp.Connected)){ns = tcp.GetStream();StateObject state = new StateObject();state.client = tcp;NetworkStream stream = state.client.GetStream();if (stream.CanRead){byte[] buffer = new byte[tcp.ReceiveBufferSize];stream.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(AsyncReadCallBack), state);}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

NetworkStream读取处理

private void AsyncReadCallBack(IAsyncResult iar)
{StateObject state = (StateObject)iar.AsyncState;if ((state.client == null) || (!state.client.Connected)) return;int NumOfBytesRead;NetworkStream ns = state.client.GetStream();NumOfBytesRead = ns.EndRead(iar);if (NumOfBytesRead > 0){byte[] buffer = new byte[NumOfBytesRead];Array.Copy(state.buffer, 0, buffer, 0, NumOfBytesRead);ReceiveAppend(buffer, TcpUdp.StringType.String);ns.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(AsyncReadCallBack), state);}else{ns.Close();state.client.Close();ns = null;state = null;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

NetworkStream发送

if (TcpIsOpen)
{if (ns != null){//ns.Write(buffer, 0, buffer.Length);ns.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(StreamWriteCallBack), ns);}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
private void StreamWriteCallBack(IAsyncResult iar)
{NetworkStream ns = (NetworkStream)iar.AsyncState;ns.EndWrite(iar);
}

这篇关于TcpClient类异步接收数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Java 中实现异步的多种方式

《Java中实现异步的多种方式》文章介绍了Java中实现异步处理的几种常见方式,每种方式都有其特点和适用场景,通过选择合适的异步处理方式,可以提高程序的性能和可维护性,感兴趣的朋友一起看看吧... 目录1. 线程池(ExecutorService)2. CompletableFuture3. ForkJoi

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分