Stream.Read 方法

当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。

语法

public abstract int Read(byte[] buffer, int offset, int count)

参数

  • buffer: 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。

  • offsetbuffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。

  • count: 要从当前流中最多读取的字节数。

返回值

读入缓冲区中的总字节数。如果当前可用的字节数没有请求的字节数那么多,则总字节数可能小于请求的字节数,或者如果已到达流的末尾,则为零 (0)。

备注

此方法的实现从当前流中读取最多的 count 个字节,并将它们存储在从 offset 开始的 buffer 中。流中的当前位置提升已读取的字节数;但是,如果出现异常,流中的当前位置保持不变。实现返回已读取的字节数。仅当位置当前位于流的末尾时,返回值才为零。如果没有任何可用的数据,该实现将一直阻塞到至少有一个字节的数据可读为止。仅当流中不再有其他的数据,而且也不再需要更多的数据(如已关闭的套接字或文件尾)时,Read 才返回 0。即使尚未到达流的末尾,实现仍可以随意返回少于所请求的字节。

之前一般采用如下方式进行数据接收:

  int recv;//定义接收数据长度变量IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text));//接收端所监听的接口,ip也可以用IPAddress.AnySocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一个Socket对象socket.Bind(ipEnd);//绑定套接字到一个IP地址和一个端口上(bind());socket.Listen(10);while (true){byte[] data = new byte[1024];//对data清零Socket clientSocket = socket.Accept(); //一旦接受连接,创建一个客户端recv = clientSocket.Receive(data);if (recv == 0) //如果收到的数据长度小于0,则退出break;string stringData = "0x" + BitConverter.ToString(data).Replace("-", " 0x").ToLower();this.Invoke((EventHandler)delegate{richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss")  + stringData + "\n";});}

之前用的时候没发现什么问题,但是今天在测试金属门数据接收的时候发现会丢数据,金属门每隔十秒给我一次数据,用上面这个差不多60秒才能收到一组数据,针对以上问题,做了如下修改:

将数据接收放到 while (true),数据接收正常

以下分别采用三种方式实现了数据的正常接收,代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace MetalGate
{public partial class MainForm : Form{public MainForm(){InitializeComponent();}private BackgroundWorker demoBGWorker = new BackgroundWorker();static TcpClient tcpClient;static NetworkStream stream;private void MainForm_Load(object sender, EventArgs e){textBox1.Text = "192.168.1.99";textBox2.Text = "8234";}//private void BGWorker_DoWork(object sender, DoWorkEventArgs e)private void BGWorker_DoWork(){var serverIPEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.99"), 8234); // 当前服务器使用的ip和端口TcpListener tcpListener = new TcpListener(serverIPEndPoint);tcpListener.Start();Console.WriteLine("服务端已启用......"); // 阻塞线程的执行,直到一个客户端连接tcpClient = tcpListener.AcceptTcpClient();Console.WriteLine("已连接.");stream = tcpClient.GetStream();          // 创建用于发送和接受数据的NetworkStreamvar t1 = new Thread(ReceiveMsg);t1.IsBackground = true;t1.Start();}private void BGWorker_DoWork1(){//在这里执行耗时的运算。int recv;//定义接收数据长度变量IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text));//接收端所监听的接口,ip也可以用IPAddress.AnySocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一个Socket对象socket.Bind(ipEnd);//绑定套接字到一个IP地址和一个端口上(bind());socket.Listen(10);//创建监听线程Thread thread = new Thread(Listen);thread.IsBackground = true;thread.Start(socket);}/// <summary>/// 等待客户端的连接 并且创建与之通信的Socket/// </summary>Socket socketSend;void Listen(object o){try{Socket socketWatch = o as Socket;while (true){socketSend = socketWatch.Accept();//等待接收客户端连接                  //开启一个新线程,执行接收消息方法Thread r_thread = new Thread(Received);r_thread.IsBackground = true;r_thread.Start(socketSend);}}catch { }}/// <summary>/// 服务器端不停的接收客户端发来的消息/// </summary>/// <param name="o"></param>void Received(object o){try{Socket socketSend = o as Socket;while (true){//客户端连接服务器成功后,服务器接收客户端发送的消息byte[] buffer = new byte[1024 * 1024 * 3];//实际接收到的有效字节数int len = socketSend.Receive(buffer);if (len == 0){break;}// string str = Encoding.UTF8.GetString(buffer, 0, len);string stringData = "0x" + BitConverter.ToString(buffer, 0, len).Replace("-", " 0x").ToLower();this.Invoke((EventHandler)delegate{richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss -*- ") + stringData + "\n";});}}catch { }}private void BGWorker_DoWork2(){int recv;//定义接收数据长度变量IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text));//接收端所监听的接口,ip也可以用IPAddress.AnySocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一个Socket对象socket.Bind(ipEnd);//绑定套接字到一个IP地址和一个端口上(bind());socket.Listen(10);new Thread(delegate (){Socket clientSocket = null;while (true){Stopwatch sw = new Stopwatch();// 开始计时sw.Start();clientSocket = socket.Accept(); //一旦接受连接,创建一个客户端Task.Run(() =>{while (true){byte[] data = new byte[50];//对data清零recv = clientSocket.Receive(data, 0, data.Length, SocketFlags.None);//if (recv == 0) //如果收到的数据长度小于0,则退出//    break;string stringData = "0x" + BitConverter.ToString(data, 0, recv).Replace("-", " 0x").ToLower();this.Invoke((EventHandler)delegate{richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss -*- ") + stringData + "\n";});//结束计时  sw.Stop();long times = sw.ElapsedMilliseconds;this.Invoke((EventHandler)delegate{richTextBox1.Text += "执行查询总共使用了" + times + "毫秒" + "\n";});}});}}){ IsBackground = true }.Start();}void ReceiveMsg(){byte[] buffer = new byte[1024]; // 预设最大接受1024个字节长度,可修改int count = 0;try{while ((count = stream.Read(buffer, 0, buffer.Length)) != 0){string stringData = "0x" + BitConverter.ToString(buffer, 0, count).Replace("-", " 0x").ToLower();Console.WriteLine($"{tcpClient.Client.LocalEndPoint.ToString()}:{DateTime.Now.ToString("yy-MM-dd hh:mm:ss -*- ") + stringData + "\n"}");this.Invoke((EventHandler)delegate{richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss -*- ") + stringData + "\n";});}}catch(Exception ex){Console.WriteLine(ex.Message);}}private void SendData(IPAddress remoteIP, int Port, byte[] bits){//实例化socket               Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint ipep = new IPEndPoint(remoteIP, Port);socket.Connect(ipep);//socket.Send(bits, 8, SocketFlags.None);socket.Send(bits);socket.Close();}private void btnListen_Click(object sender, EventArgs e){//demoBGWorker.DoWork += BGWorker_DoWork;//demoBGWorker.RunWorkerAsync();//Task.Run(() =>// {BGWorker_DoWork2();//});}private void btnSend_Click(object sender, EventArgs e){byte[] order = new byte[8];order = new byte[] { 0x80, 0x04, 0x00, 0x7F };SendData(IPAddress.Parse("192.168.1.100"), int.Parse("49558"), order);MessageBox.Show("指令发送成功");}}
}

测试:

Task.Run(() => {}); 这个可以去掉;

C# 三种方式实现Socket数据接收(经典)相关推荐

  1. vue前端常用的三种方式模拟获取数据

    前端的三种方式模拟获取数据 1⃣️.mockjs插件获取: 1.首先我们先进行安装mockjs,进入项目在终端输入:npm install mockjs --save 2.我们可以在src目录下新建m ...

  2. 【Java基础】IO流概述分类、字节流写数据、字节流写数据的三种方式及写数据的两个小问题

    目录 一.IO流概述和分类 二.字节流写数据 三.字节流写数据的三种方式 四.字节流写数据的两个小问题 一.IO流概述和分类 IO流介绍: ● IO:输入/输出(Input/Output) ● 流:是 ...

  3. 据采集的三种方式-如何获取数据

    随着社会的不停地发展.人们也是越来越离不开互联网,今天小编就给大家盘点一下免费收集数据的方法有三种,只需要点几下鼠标就能轻松获取数据,不管是导出excel还是自动发布到网站.详细参考图片一.二.三.四 ...

  4. 三种方式实现观察者模式 及 Spring中的事件编程模型

    观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧, ...

  5. ajax上传多文件和数据,Ajax上传数据和上传文件(三种方式)

    Ajax向后端发送数据可以有三种方式:原生Ajax方式,jQuery Ajax方式,iframe+form 方式(伪造Ajax方式) Title .btn { background-color: co ...

  6. discard connection丢失数据_python kafka 生产者发送数据的三种方式

    python kafka 生产者发送数据的三种方式 发送方式 同步发送 发送数据耗时最长 有发送数据的状态,不会丢失数据,数据可靠性高 以同步的方式发送消息时,一条一条的发送,对每条消息返回的结果判断 ...

  7. 数据导入HBase最常用的三种方式及实践分析

    要使用Hadoop,数据合并至关重要,HBase应用甚广.一般而言,需要针对不同情景模式将现有的各种类型的数据库或数据文件中的数据转入至HBase中. 常见方式为:1.使用HBase的API中的Put ...

  8. SQL:使用备份向导、SQL命令、导出数据三种方式对已建立的数据库进行备份

    SQL:使用备份向导.SQL命令.导出数据三种方式对已建立的数据库进行备份 目录 题目要求 解题步骤 题目要求 使用备份向导备份数据库 "DEMO_4_2_2_1"到考生文件夹&q ...

  9. Docker的常用管理命令Docker将数据挂载到容器的三种方式

    文章目录 镜像管理命令 容器管理常用命令 docker run常用参数 Docker run的其他参数 docker 创建容器命令 容器资源限制 docker管理容器常用命令 docker将数据挂载到 ...

最新文章

  1. HLG 1481 Attack of the Giant n-pus【二分+二分图完全匹配】
  2. Gradle构建脚本概要之构建块
  3. 做产品必须知道的:从产品助理到产品总监的职业进阶
  4. 和男朋友一块儿吃VS单独一人在家吃饭
  5. c mysql 查询超时设置_MySQL查询超时的设置方法
  6. linux mysql使用
  7. Python中lambda的使用,与它的三个好基友介绍!
  8. 语言身高预测实验注意事项_?新预训练模型CodeBERT出世,编程语言和自然语言都不在话下...
  9. Linux系统通过Squid配置实现代理上网
  10. Windows命令之ping命令
  11. c语言32关键字详解pdf,C语言32个关键字.pdf
  12. 复变函数的极限和连续
  13. 国产旗舰手机定价近六千,却连iPhone12都打不过,用户选谁很明确
  14. 方根法公式_(完整word版)层次分析法中用方根法计算权重在Excel中的具体操作
  15. 一曲《千秋令》,唱不尽千古风华
  16. 燕十八 mysql优化_布尔教育燕十八mysql优化视频资料分享
  17. Mni2440 linux PWM 驱动代码修改支持 频率,占空比修改--XiaoLin.Peng
  18. 推荐一款firefox的flv下载插件
  19. ios蓝牙开发 ------ CoreBluetooth 教程lt;转gt;
  20. 计算机80000歌曲,2017年度最受欢迎歌曲,网易云音乐收藏量最高的60首

热门文章

  1. 每天写出好代码的5个建议
  2. [转载].SSRAM、SDRAM和Flash简要介绍
  3. 爱情二十九课,驾驭爱情
  4. PHP生成各种验证码和Ajax验证
  5. 一 流程控制之if判断
  6. pycharm(windows)安装及其设置中文菜单
  7. highcharts动态获取数据生成图表问题
  8. 【F12一下,看看页面里的第一行】——说说浏览器兼容性模式
  9. ORACLE备份中的压缩
  10. echo和@echo_如何在Echo Show和Echo Spot上切换到24小时时钟