C#串口通信—傳輸文件測試,
說明:該程序可能不具備實用性,僅測試用。
一、使用虛擬串口工具VSPD虛擬兩個串口COM1和COM2

二、約定
占一個字節,代碼如下:

![]()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace COMClient
{
/// <summary>
/// 約定
/// </summary>
public enum Protocol
{
Client端發送文件名 = 0,
Client端發送數據塊 = 1,
Client端發送最後一個數據塊 = 2,
Server端本次接收完畢 = 3,
Server端結束 = 4
}
}
View Code
三、功能說明:
COMClient程序監聽COM1串口,COMServer程序監聽COM2串口。COMClient先擇文件,發送,COMServer接收文件。數據分多次發送,每次發送的數據,通過第一個字節判斷發送的這段數據是干啥的,後面的字節是數據本身。
四、COMClient端發送文件
代碼:

![]()
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Threading;
namespace COMClient
{
public partial class Form1 : Form
{
#region 變量
/// <summary>
/// 串口資源
/// </summary>
private static SerialPort serialPort = null;
/// <summary>
/// 文件
/// </summary>
private static FileStream fs = null;
private static long index = 0;
private static long blockCount;
private static int size = 4095;
private static DateTime dt;
#endregion
#region Form1
public Form1()
{
InitializeComponent();
}
#endregion
#region Form1_Load
private void Form1_Load(object sender, EventArgs e)
{
serialPort = new SerialPort("COM1");
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
serialPort.Open();
}
#endregion
#region btnConn_Click
private void btnConn_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
dt = DateTime.Now;
fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
blockCount = (fs.Length - 1) / size + 1;
List<byte> bList = new List<byte>();
bList.Add((int)Protocol.Client端發送文件名);
bList.AddRange(ASCIIEncoding.UTF8.GetBytes(openFileDialog1.FileName));
byte[] bArr = bList.ToArray();
serialPort.Write(bArr, 0, bArr.Length);
}
}
#endregion
/// <summary>
/// 接收串口數據事件
/// </summary>
public void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (serialPort.BytesToRead == 0) return;
int bt = serialPort.ReadByte();
switch (bt)
{
case (int)Protocol.Server端本次接收完畢:
if (index != blockCount - 1)
{
byte[] bArr = new byte[size + 1];
bArr[0] = (int)Protocol.Client端發送數據塊;
fs.Read(bArr, 1, size);
index++;
Thread.Sleep(1);
serialPort.Write(bArr, 0, bArr.Length);
}
else
{
byte[] bArr = new byte[fs.Length - (size * index) + 1];
bArr[0] = (int)Protocol.Client端發送最後一個數據塊;
fs.Read(bArr, 1, bArr.Length - 1);
index++;
serialPort.Write(bArr, 0, bArr.Length);
}
break;
case (int)Protocol.Server端結束:
index = 0;
double totalSeconds = DateTime.Now.Subtract(dt).TotalSeconds;
MessageBox.Show("完成,耗時" + totalSeconds + "秒,速度" + (fs.Length / 1024.0 / totalSeconds).ToString("#.0") + "KB/S");
fs.Close();
fs.Dispose();
break;
}
}
}
}
View Code
五、COMServer端接收文件
代碼:

![]()
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace COMServer
{
public partial class Form1 : Form
{
#region 變量
/// <summary>
/// 串口資源
/// </summary>
private static SerialPort serialPort = null;
/// <summary>
/// 文件
/// </summary>
private static FileStream fs = null;
#endregion
#region Form1
public Form1()
{
InitializeComponent();
}
#endregion
#region Form1_Load
private void Form1_Load(object sender, EventArgs e)
{
serialPort = new SerialPort("COM2");
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
serialPort.Open();
}
#endregion
/// <summary>
/// 接收串口數據事件
/// </summary>
public void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (serialPort.BytesToRead == 0) return;
#region 接收數據
int bt = serialPort.ReadByte();
List<byte> bList = new List<byte>();
while (serialPort.BytesToRead > 0)
{
byte[] bArr = new byte[serialPort.BytesToRead];
serialPort.Read(bArr, 0, bArr.Length);
bList.AddRange(bArr);
}
byte[] receiveData = bList.ToArray();
#endregion
switch (bt)
{
case (int)Protocol.Client端發送文件名:
string path = ASCIIEncoding.UTF8.GetString(receiveData);
string fileName = Path.GetFileName(path);
fs = new FileStream(@"d:\_臨時文件\COM測試" + fileName, FileMode.Create, FileAccess.Write);
byte[] bArr = new byte[1];
bArr[0] = (int)Protocol.Server端本次接收完畢;
serialPort.Write(bArr, 0, bArr.Length);
break;
case (int)Protocol.Client端發送數據塊:
fs.Write(receiveData, 0, receiveData.Length);
fs.Flush();
bArr = new byte[1];
bArr[0] = (int)Protocol.Server端本次接收完畢;
serialPort.Write(bArr, 0, bArr.Length);
break;
case (int)Protocol.Client端發送最後一個數據塊:
fs.Write(receiveData, 0, receiveData.Length);
fs.Flush();
bArr = new byte[1];
bArr[0] = (int)Protocol.Server端結束;
serialPort.Write(bArr, 0, bArr.Length);
fs.Close();
fs.Dispose();
break;
}
}
}
}
View Code