为了使用串口通信,可以发送文字、图片、声音、文件等,实现了一个小的程序。
程序的框架,决定采用window form的界面,参考QQ聊天界面和声音等,实现双工低速率4kbps的通信。界面主要实现一些按钮和必要的建立连接的装置。后面其他的代码实现相应的功能,可以说是采用了某种模型吧。
一、串口出现的问题
1、不能按照我们的目的接收bytes
解决方案是:采用有固定格式的帧,采用的帧长 LengthOfFrame=180,这个纯属自己的爱好,以后所有的帧都是这么长。然后是定义帧的形式。采用帧头长LengthOfHeader=2,剩下的部分长度LengthOfDataFrame=180-2=178,第一个数据表示该帧的类型,第二个数据表示该帧的实际长度,由于帧长是180<,buffer[0]=(byte)tag,buffer[1]=(byte)LengthOfThisFrame,考虑可能有过长的帧,我们要特殊处理一下。如果后面还有该帧的后续帧,则该帧的长度buffer[1]=0x00,设为一个标记,表示本帧的长度是LengthOfDataFrame,还有下一帧也是本帧的一部分。具体的程序,见下面的程序。
#region const parameters
const int LengthOfFrame = 180;
const int LengthOfHeaderDataFrame = 2;
const int LengthOfDataFrame = LengthOfFrame - LengthOfHeaderDataFrame;
const byte DataTag = (byte)'d';
const byte CMDTag = (byte)'c';
const byte FileTag = (byte)'f';
const byte VoiceTag = (byte)'v';
static Encoding MyEncoding = Encoding.Unicode;
// here we use utf16,that is two bytes,which can express Chinese and English
#endregion
下面是发送帧的部分程序。
public static void SendBytesBySerialPort(byte[] Buf, byte tag)
{
if (Buf == null) return;
int length = Buf.Length;
byte[] outBuf = new byte[LengthOfFrame];
int sendTimes_1 = length / LengthOfDataFrame;
int lastTimesLength = length % LengthOfDataFrame;
// if Buf is too long, then divided into dataLength
for (int i = 0; i < sendTimes_1; i++)
{
outBuf[0] = tag;
outBuf[1] = 0x00;
for (int j = 0; j < LengthOfDataFrame; j++)
{
outBuf[2 + j] = Buf[i * LengthOfDataFrame + j];
}
if (lastTimesLength == 0 && i == sendTimes_1 - 1)
outBuf[1] = LengthOfDataFrame;
proxySerialPort.Write(outBuf, 0, LengthOfFrame);
}
// send the last information
if (lastTimesLength > 0)
{
outBuf[0] = tag;
outBuf[1] = (byte)lastTimesLength;
for (int j = 0; j < lastTimesLength; j++)
{
outBuf[j + 2] = Buf[sendTimes_1 * LengthOfDataFrame + j];
}
proxySerialPort.Write(outBuf, 0, LengthOfFrame);
}
}
上面的程序就算是从发送部分解决问题。
下面从数据接收部分解决问题,接收出现的最多问题是,DataReceived调用的时候,不是每次都有恰好那么多个字节,这个就需要多次接收,堆积在一起。接着出现,有数据来了,系统不调用这个DataReceived,更是无语,只好采用一直调用DataReceived的方法了。具体代码如下:
n