C#|C# 三种方式实现Socket数据接收
目录
- Stream.Read 方法
- 将数据接收放到 while (true)
Stream.Read 方法 当在派生类中重写时,从当前流读取字节序列,并将此流中的位置提升读取的字节数。
语法:
public abstract int Read(byte[] buffer, int offset, int count)
参数:
buffer
: 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的offset
和 ( offset +count -1
) 之间的值由从当前源中读取的字节替换。offset
:buffer
中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。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 = https://www.it610.com/article/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) 将数据接收放到 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); }/// /// 等待客户端的连接 并且创建与之通信的Socket/// 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 { }}/// /// 服务器端不停的接收客户端发来的消息/// /// 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 = "https://www.it610.com/article/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 = https://www.it610.com/article/new byte[50]; //对data清零recv = clientSocket.Receive(data, 0, data.Length, SocketFlags.None); //if (recv == 0) //如果收到的数据长度小于0,则退出//break; string stringData ="https://www.it610.com/article/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 = "https://www.it610.com/article/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){//实例化socketSocket 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("指令发送成功"); }}}
![C#|C# 三种方式实现Socket数据接收](https://img.it610.com/image/info11/6739e459988f4150b09fbe92963a028d.jpg)
文章图片
![C#|C# 三种方式实现Socket数据接收](https://img.it610.com/image/info11/b53827152b4446aeb2b69c0c38cd66bd.jpg)
文章图片
【C#|C# 三种方式实现Socket数据接收】到此这篇关于
C#
三种方式实现Socket
数据接收的文章就介绍到这了,更多相关C#
实现Socket
数据接收内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus|mybatisplus where QueryWrapper加括号嵌套查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM