大家帮忙看下c# SerialPort控件短信猫读取数据不完整

完美追求 2010-11-11 01:06:20
用.net 自带的serialport控件读出数据经常出现读出的数据不完整(以下是原代码)
请高手指点一下


private SerialPort serialPort = new System.IO.Ports.SerialPort();
private PDU_DeCoding SmsSend = new PDU_DeCoding();
private PDUCoding sms=new PDUCoding();
private void Form1_Load(object sender, EventArgs e)
{
f_BG.DoWork += new DoWorkEventHandler(f_BG_DoWork);
f_BG.RunWorkerAsync();
btnClose.Enabled = false;
string[] portNames = SerialPort.GetPortNames();
for (int i = 0; i < portNames.Length; i++)
{
cmbCom.Items.Add(portNames[i]);
}
if (portNames.Length > 0)
{
cmbCom.SelectedIndex = 0;
}
}
public delegate void myDelegate(string text);

public void updateTextBox(string text)
{
lbcontent.Items.Add(text);

}
public StringBuilder sb = new StringBuilder();
public void AddReceiveData(string text)
{
lock (sb)
{
sb.Append(text);
}
}
private void serialPort_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(1000);

System.IO.Ports.SerialPort serialPort = (System.IO.Ports.SerialPort)sender;
string strReceive = string.Empty;
string strCollect = string.Empty;

byte[] Buffer = new byte[serialPort.BytesToRead];
serialPort.Read(Buffer, 0, Buffer.Length);
strReceive = Encoding.ASCII.GetString(Buffer);
lbcontent.BeginInvoke(new myDelegate(updateTextBox), "收到com口数据" + strReceive + "\n");
strCollect += strReceive;
BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
bgWorker.RunWorkerAsync(strCollect);
}

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
string bs = (string)e.Argument;
AddReceiveData(bs);

}
private void btnconnect_Click(object sender, EventArgs e)
{
serialPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
if (serialPort.IsOpen)
{
serialPort.Close();
}
try
{
serialPort.PortName = cmbCom.SelectedItem.ToString();
serialPort.BaudRate = 9600;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = System.IO.Ports.StopBits.One;
serialPort.RtsEnable = true;
serialPort.WriteBufferSize = 1024;
serialPort.ReadBufferSize = 1024;
serialPort.ReadTimeout = 2500;
serialPort.Open();
byte[] buffer = Encoding.ASCII.GetBytes("AT\r");
serialPort.Write(buffer, 0, buffer.Length);
System.Threading.Thread.Sleep(150);
string Data = serialPort.ReadExisting();
if (Data.IndexOf("OK") != -1)
{

lbcontent.Items.Add("COM口返回数据:" + Data);
lbcontent.Items.Add("连接" + serialPort.PortName + "成功\n");
buffer = Encoding.ASCII.GetBytes(txtmoblie.Text + "\r");
serialPort.Write(buffer, 0, buffer.Length);
lbcontent.Items.Add("向COM口发送数据:" + txtmoblie.Text + "\n");
System.Threading.Thread.Sleep(100);
string d = serialPort.ReadExisting();
// string d = "\r\n+CSCA: \"+8613800100500\",145\r\n\r\nOK\r\n";
//去掉\r\n
int start = d.IndexOf("86");
if (start != -1)
{
txtSMSCenter.Text = d.Substring(start, 13);
lbcontent.Items.Add("短信中心号码" + d.Substring(start, 13));
lbcontent.Items.Add("Com口返回数据" + d);

}
btnconnect.Enabled = false;
btnClose.Enabled = true;
serialPort.DiscardInBuffer();
}
else
{
MessageBox.Show("连接失败");
}


}
catch (Exception ex)
{
lbcontent.Items.Add(ex.ToString());
}
finally
{
serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
}
}

private void btnClose_Click(object sender, EventArgs e)
{
try
{

serialPort.Close();
lbcontent.Items.Add("断开"+serialPort.PortName+"成功\n");
btnClose.Enabled = false;
btnconnect.Enabled = true;
}catch(Exception ex)
{
lbcontent.Items.Add(ex.ToString());
}

}

private void btnSend_Click(object sender, EventArgs e)
{
serialPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler
(serialPort_DataReceived);
string decodeSMS = SmsSend.smsDecodedsms(txtSMSCenter.Text,txtmoblie.Text.Trim(),txtcontent.Text);
byte[] buf = Encoding.ASCII.GetBytes(String.Format("AT+CMGS={0}\r", SmsSend.nLength));
serialPort.Write(buf,0,buf.Length);
System.Threading.Thread.Sleep(200);
string response = serialPort.ReadExisting();
if (response.Length > 0 && response.EndsWith("> "))
{
buf = Encoding.ASCII.GetBytes(string.Format("{0}\x01a", decodeSMS));
serialPort.Write(buf, 0, buf.Length);
lbcontent.Items.Add("向手机号:"+txtmoblie.Text+";发送:"+txtcontent.Text+"成功\n");
}
serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
}

private void f_BG_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
System.Threading.Thread.Sleep(200);
lock(sb)
{
string response = sb.ToString();

if (response.Length > 0 && response.IndexOf("+CMT:") != -1)
{
response = response.Replace("\r\n", "|");
int i = response.IndexOf("|");
if (i == 0)
{
i = 1;
}
else
{
i = 0;
}

i = response.IndexOf("|", i);
response = response.Remove(0, i);
response = response.Replace("|", "");


string SendPhoneNumber = "";
string SendContent = "";
DateTime SendTime = new DateTime();

string SCA = "";
PDUCoding.GSMCode code = new PDUCoding.GSMCode();
if (sms.DecodingMsg(response, ref SendPhoneNumber, ref SendContent, ref SendTime, ref code, ref SCA))
{
lbcontent.BeginInvoke(new myDelegate(updateTextBox), SendPhoneNumber.ToString() + "于" + SendTime.ToString() + "发来信息:" + SendContent.ToString());
if (SendContent.Substring(0, 2) == "查询")
{
//serialPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
string decodeSMS = SmsSend.smsDecodedsms(txtSMSCenter.Text, SendPhoneNumber.ToString(), "您的查询是");
byte[] buf = Encoding.ASCII.GetBytes(String.Format("AT+CMGS={0}\r", SmsSend.nLength));
serialPort.Write(buf, 0, buf.Length);
System.Threading.Thread.Sleep(200);
string response1 = serialPort.ReadExisting();
if (response1.Length > 0 && response1.EndsWith("> "))
{
buf = Encoding.ASCII.GetBytes(string.Format("{0}\x01a", decodeSMS));
serialPort.Write(buf, 0, buf.Length);
lbcontent.BeginInvoke(new myDelegate(updateTextBox), "向手机号:" + txtmoblie.Text + ";发送:" + txtcontent.Text + "成功\n");
}
//serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort_DataReceived);
}
}
sb.Remove(0, sb.Length);
}
}
}
}


...全文
381 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
完美追求 2010-11-13
  • 打赏
  • 举报
回复
谢谢了,我找到方法了,不是大家所说的问题,是我在接收短信时少给串口发了一个命令
完美追求 2010-11-11
  • 打赏
  • 举报
回复
怎么高手都不在吗????
完美追求 2010-11-11
  • 打赏
  • 举报
回复
怎么高手都不在吗????
lonyjianhui 2010-11-11
  • 打赏
  • 举报
回复
终于睡醒了,你的问题我也曾经出现过这个问题,你往下面几个方面检查一下吧,你的代码太乱了,没心思看,就只看了接收数据的部分。
1.接收缓冲区大小不够:看了一下你的代码,发现你的缓冲区是不断改变的,最好固定一下,给个例子吧

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bytes = serialPort1.BytesToRead; //得到数据长度
buffer = new byte[2048]; //接收缓冲区
serialPort1.Read(buffer, 0, bytes); //读取数据
string str_pass = "";
str_pass = Encoding.ASCII.GetString(buffer, 0, bytes);
setText1(str_pass); //
if (bRecievemsg) //
{ //处理数据
msg.Add(str_pass); //
setText2(msg); //
}
}


2.发送端发送太快,以致接收端来不及处理,这个,你好像是做短信的,一般没有这个问题;
3.硬件问题,如果硬件有问题,会出现接收乱码或其它一系列问题;
4.其它:与接收无太大关系,可能是其它处理导致的。例如,看到你的接收方法中有System.Threading.Thread.Sleep(1000);一句,当然我不是说这句一定有问题,我是想说,每一句都应该有它的作用,在必要的时候选用合适的语句是个很好的编程方式,也就是,不要滥用语句,由于代码太长太乱,我就不仔细看了哈。

兔子-顾问 2010-11-11
  • 打赏
  • 举报
回复
建议你直接DataReceived中用ReadLine,记得之前先设置SerialPort对象的NewLine属性为"\r\n"
OLillian 2010-11-11
  • 打赏
  • 举报
回复
我用 serialport.close() 关闭串口,会出现“因为执行绪结束或应用程式要求,所以已中止I/O操作” 错误。看大家都是直接调用 serialport.close() 关闭串口,怎么都没出问题。请高手多指教
完美追求 2010-11-11
  • 打赏
  • 举报
回复
我的问题是,我读到的数据不完整只读出来:+CMTI:"SM",40

正常短信猫有短信应该读到的数据是下面这些
+CMT: ,14\r\n0891683108100005F0240D91683193816129F621085040421201502368767D98864EBA751F51997167003A8D775F976BD49E2190FD65E9002C5E725F976BD49A7490FD7D2F002C54035F976BD4732A90FD5DEE002C4E0B73ED6BD45C0F59D090FD665A002C63235F976BD46C115DE590FD5C11002C770B8D7767656BD48C0190FD597D0021\r\n"
兔子-顾问 2010-11-11
  • 打赏
  • 举报
回复
代码太长。下次记得用UBB标记一下。c系列代码没格式很难找括号对应关系。

你的代码

大致看了一下,因为没注解,只看了关键的Reveived方法,比较多的多余代码,不一定就会错,但是多一步不是100%正确的代码就有一点可能性。比如数据读取可以改为ReadExisting而不是搬到缓存中再处理。你的问题是什么?
lonyjianhui 2010-11-11
  • 打赏
  • 举报
回复
我做过,但是。。。
ycui_hong

等 级:
结帖率:50.00%

等下吧

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧