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.Any
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一個Socket物件
socket.Bind(ipEnd);//系結套接字到一個IP地址和一個埠上(bind());
socket.Listen(10);
while (true)
{
byte[] data = https://www.cnblogs.com/zls366/archive/2021/10/16/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(); // 創建用于發送和接受資料的NetworkStream
var 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.Any
Socket 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 = "https://www.cnblogs.com/zls366/archive/2021/10/16/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.Any
Socket 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.cnblogs.com/zls366/archive/2021/10/16/new byte[50];//對data清零
recv = clientSocket.Receive(data, 0, data.Length, SocketFlags.None);
//if (recv == 0) //如果收到的資料長度小于0,則退出
// break;
string stringData ="https://www.cnblogs.com/zls366/archive/2021/10/16/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.cnblogs.com/zls366/archive/2021/10/16/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("指令發送成功");
}
}
}


----------------------------------------------------
以上就是本節的全部內容,如果感覺有用,請多多的點擊在看和分享,需要進技術交流群的,請加小編微信zls20210502,切記備注 進群!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/319541.html
標籤:.NET技术
上一篇:C# 正則運算式撰寫及驗證方法
