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 中的异步与同步深度解析(实践记录)

《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. 问题根源二、问题详细分

Java中将异步调用转为同步的五种实现方法

《Java中将异步调用转为同步的五种实现方法》本文介绍了将异步调用转为同步阻塞模式的五种方法:wait/notify、ReentrantLock+Condition、Future、CountDownL... 目录异步与同步的核心区别方法一:使用wait/notify + synchronized代码示例关键

springboot的调度服务与异步服务使用详解

《springboot的调度服务与异步服务使用详解》本文主要介绍了Java的ScheduledExecutorService接口和SpringBoot中如何使用调度线程池,包括核心参数、创建方式、自定... 目录1.调度服务1.1.JDK之ScheduledExecutorService1.2.spring

异步线程traceId如何实现传递

《异步线程traceId如何实现传递》文章介绍了如何在异步请求中传递traceId,通过重写ThreadPoolTaskExecutor的方法和实现TaskDecorator接口来增强线程池,确保异步... 目录前言重写ThreadPoolTaskExecutor中方法线程池增强总结前言在日常问题排查中,

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery