前言
本文主要是提供一个TCP通讯的Demo。有时候上位机需要通过TCP来进行文件与数据传输,相对于基础的IO与串口,TCP的传输内容可能更加复杂,本文尽量从多个角度来给出示例。
关于上位机的搭建与通讯我们已经有以下几个部分可供参考:
C#上位机:串口通讯
C#上位机:Modbus RTU通讯实例
C#上位机:Modbus TCP通讯实例
概念提要:
TCP通讯:一种字节流传输层通讯协议,流程为建立连接-传输数据-释放连接。
实现方式:Socket编程
监听IP:监听一个IP地址,当有数据传输时,进行接收,当无数据时保持对IP地址的监听状态。
模拟通讯:软件名:Hercules,提供TCP Clien与Server的测试端口。
数据传输
首先添加Socket
using System.Net;
using System.Net.Sockets;
using System.Threading;
然后在代码层添加监听
public partial class Form1 : Form
{
TcpListener listener;
public Form1()
{
InitializeComponent();
}
}
然后我们以Client的形式向主站建立连接并发送数据。
/// <summary>
/// 发送数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void send_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
try
{
client.Connect(IPAddress.Parse(txtIp.Text), int.Parse(txtPort.Text));//建立连接
NetworkStream ns = client.GetStream();
int size = 9;
byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ns.Write(buffer, 0, size);
ns.Flush();
ns.Close();
}
catch
{
}
}
然后我们监听一个IP地址,等待Client向该IP发送数据
/// <summary>
/// 开始监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lisBegin_Click(object sender, EventArgs e)
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), int.Parse("501"));
listener.Start();
//MessageBox.Show("开始监听");
Thread th = new Thread(ReceiveMsg);//启用监听线程
th.Start();
th.IsBackground = true;
button1.Text = "正在监听";//锁掉按键并显示状态
button1.Enabled = false;
}
catch
{
MessageBox.Show("IP地址错误,监听失败");
}
}
/// <summary>
/// 监听线程
/// </summary>
public void ReceiveMsg()
{
while (true)
{
try
{
int size = 0;
int len = 0;
TcpClient client = listener.AcceptTcpClient();
if (client.Connected)
{
MessageBox.Show("连接成功");
}
NetworkStream stream = client.GetStream();
if (stream != null)
{
byte[] buffer = new byte[512];
while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
{
string s = Convert.ToString(buffer[0]);//输出第一位来检查连接
MessageBox.Show(s);
len += size;
}
}
}
catch (Exception ex)
{
MessageBox.Show("异常:" + ex.Message);
}
}
}
我们启动监听,并打开Hercules,用Client启动连接,并随意发送一段数据:
数据传输测试完成。
另:我们对一个端口监听的状态,不随Client的连接状态而发生改变,在实际上的生产中,我们的脚本或者是上位机可以保持长时间不间断的监听一个本地ip,并可以用Switch等硬件来实现一种类似数据采集卡的效果。
文件传输
我们以传输图片为例子,在这一步的操作中,我们在发送端要将一个文件整合成字节流发送,接收后我们再将字节流整合成文件。
首先提取文件:
FileStream fs = new FileStream(txtFileName.Text, FileMode.Open);
在发送过程中将文件流整合为字节流:
size = fs.Read(buffer, 0, buffer.Length);
ns.Write(buffer, 0, size);
这便完成了文件的发送。文件的接收则是,将字节流按照格式整合成一个文件:
string path1 = saveadress.Text;
string path = path1 +Id + ".JPG";
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
在接收时:
byte[] buffer = new byte[512];
while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, size);
len += size;
}
Demo设计与完整代码
我们设计一个发送与接收同端的Demo来进行测试代码的可行性,也就是自发自接。大概可如下:
/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void sendPhoto_Click(object sender, EventArgs e)
{
string s;
TcpClient client = new TcpClient();
try
{
string Path= Path.Text;
FileStream fs = new FileStream(Path, FileMode.Open);
try
{
client.Connect(IPAddress.Parse("127.0.0.1"), int.Parse("501"));//请自行向前端要ip
NetworkStream ns = client.GetStream();
int size = 0;//初始化读取的流量为0
long len = 0;//初始化已经读取的流量
while (len < fs.Length)
{
byte[] buffer = new byte[512];
size = fs.Read(buffer, 0, buffer.Length);
ns.Write(buffer, 0, size);
len += size;
}
fs.Flush();
ns.Flush();
fs.Close();
ns.Close();
MessageBox.Show( "文件发送成功");
}
catch
{
fs.Flush();
//ns.Flush();
fs.Close();
MessageBox.Show("文件发送失败");
Thread.Sleep(800);
}
}
catch
{
MessageBox.Show("文件地址不正确!");
}
}
/// <summary>
/// 开始监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lisBegin_Click(object sender, EventArgs e)
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), int.Parse("501"));
listener.Start();
//MessageBox.Show("开始监听");
Thread th = new Thread(ReceiveMsg);
th.Start();
th.IsBackground = true;
button1.Text = "正在监听";
button1.Enabled = false;
}
catch
{
MessageBox.Show("IP地址错误,监听失败");
}
}
/// <summary>
/// 监听线程
/// </summary>
public void ReceiveMsg()
{
while (true)
{
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
if (client.Connected)
{
MessageBox.Show("连接成功");
}
try
{
int s = 1;
int size;
int len=0;
string yy = DateTime.Now.Year.ToString(); // 2023
string mm = DateTime.Now.Month.ToString(); // 6
string path1 = saveAdress.Text;
string path = path1 + "\\" + yy + "\\" + mm + "\\" +"test "+".JPG";
string filename = path1 + "\\" + yy + "\\" + mm;
if (!Directory.Exists(filename))
{
Directory.CreateDirectory(filename);
}
while (File.Exists(path))//针对重复照片
{
path = path1 + "\\" + yy + "\\" + mm + "\\" + "(" + Convert.ToString(s) + ")" + ".JPG";
s++;
}
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
byte[] buffer = new byte[512];
while ((size = stream.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, size);
len += size;
}
fs.Flush();
stream.Flush();
stream.Close();
client.Close();
}
catch (Exception ex)
{
MessageBox.Show("异常:" + ex.Message);
}
}
}
文章来源:https://www.toymoban.com/news/detail-793178.html
测试成功。文章来源地址https://www.toymoban.com/news/detail-793178.html
到了这里,关于C#上位机:TCP通讯实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!