无法使用 gsm 调制解调器使用 System.IO.Ports 通过 C# 代码发送短信 [英] Unable to send SMS through C# code using System.IO.Ports using gsm modem

查看:23
本文介绍了无法使用 gsm 调制解调器使用 System.IO.Ports 通过 C# 代码发送短信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个按钮,当点击时,向在 NumTxt 文本框中输入的号码发送一条短信,并发送在 SMSTxt 文本框中输入的文本.在 texbox 中输入的端口名称 ComPort 这里是按钮点击事件的事件处理程序.

A button, when clicked, sends an sms to the number entered in NumTxt textbox, and sends the text entered in SMSTxt textbox. Port name entered in texbox ComPort Here's the event handler of the button click event.

  using System.IO.Ports;

  private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            int mSpeed = 1;
            serialport.PortName = ComPort.Text;
            serialport.BaudRate = 96000;
            serialport.Parity = Parity.None;
            serialport.DataBits = 8;
            serialport.StopBits = StopBits.One;
            serialport.Handshake = Handshake.XOnXOff;
            serialport.DtrEnable = true;
            serialport.RtsEnable = true;
            serialport.NewLine = Environment.NewLine;
            Console.WriteLine("1a");
            try
            {
                serialport.Open();
            }
            catch (Exception)
            {
                MessageBox.Show("Try another Port." + 
    Environment.NewLine + "Phone not detected or The requested resource is in      
    use.", "CONNECTION ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Console.WriteLine("2a");

            serialport.WriteLine("AT+CMGF=1" + Environment.NewLine);
            System.Threading.Thread.Sleep(200);
            serialport.WriteLine("AT+CSCS=GSM" + Environment.NewLine);
            System.Threading.Thread.Sleep(200);
            serialport.WriteLine("AT+CMGS=" + (char)34 + NumTxt.Text
            + (char)34 + Environment.NewLine);
            System.Threading.Thread.Sleep(200);
            serialport.WriteLine(SMSTxt.Text + (char)26);
            System.Threading.Thread.Sleep(mSpeed);
            serialport.Close();

        }
        catch (Exception)
        {
            if (serialport.IsOpen)
                serialport.Close();
            MessageBox.Show("Couldn't send the SMS.", "CONNECTION ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

昨天我能够使用这个代码发送短信,但我不知道为什么它不再起作用......没有抛出异常.当我使用gsm modem自带的软件时,我可以发送短信.但不是通过 C# 代码.如果有人能指出上面代码中的错误,我将不胜感激.

I was able to send the sms using this very code yesterday, but i do not know why it doesn't work any more.. no exceptions thrown. When I use the software that comes with gsm modem, I am able to send sms. But not through C# code. If anyone can pin point the mistake in the above code, I will be very grateful.

推荐答案

您应该永远,永远,永远使用睡眠来代替等待来自调制解调器的最终结果代码.正如您不会编写完全忽略来自 http 服务器的所有响应的 http 客户端一样,您也不应该向调制解调器发送 AT 命令并完全忽略它发回的响应.您必须阅读和解析调制解调器发送回给您的所有内容.没有其他东西能可靠地工作.

You should never, never, ever use sleep as a substitute for waiting for the Final result code from the modem. Just as you would not write a http client that completely ignores all responses from the http server, you should not send AT commands to a modem and completely ignore the responses it sends back. You must read and parse everything the modem sends back to you. Nothing else will work reliably.

我的建议是您首先获取V.250 标准 并至少阅读第 5 章的全部内容.该标准是 AT 命令处理的圣经,将教您大量有关 AT 命令处理的知识.例如,使用 WriteLine 和/或 Environment.NewLine 是错误的;AT 命令行应该以 单独结束,没有别的.

My suggestion is that you start by fetching a copy of the V.250 standard and read at least all of chapter 5. This standard is the bible for AT command handling and will teach you an enormous amount regarding AT command handling. Like for instance that using WriteLine and/or Environment.NewLine is wrong; AT command lines should be terminated with alone and nothing else.

只是强调该文件的重要性:即使在爱立信的手机中实现 AT 命令十多年后,我和我的同事仍然 定期查阅该标准.

Just to emphasis how important that document is: Even after working with implementing AT command in mobile phones in Ericsson for over a decade I and my colleagues still consulted that standard regularly.

事实上现在停止阅读这个答案,下载 那个文档,在返回阅读其余部分之前阅读第 5 章的全部内容.

In fact stop reading this answer here now, download that document, read all of chapter 5 before returning to read the rest.

对于发送你并不特别关心响应的命令1,唯一可靠的方法是做一些类似于

For sending commands where you do not particularly care about the response1, the only reliably approach is to do something similar to

serialport.Open();
...
// start sending AT+CMGF=1
serialport.Write("AT+CMGF=1
");
do {
    line = readLine(serialport);
} while (! is_final_result_code(line))
// Sending of AT+CMGF=1 command finished (successfully or not)
...
serialport.Close();

其中 readLine 函数从串行端口读取一个又一个字节,直到它接收到以 结尾的完整行,然后返回该行.

where the readLine function reads one and one byte from the serial port until it has received a complete line terminated with and then returns that line.

你可以查看atinout的代码对于 is_final_result_code 函数的示例(您还可以比较 isFinalResponseErrorisFinalResponseSuccess2"https://github.com/aferre/u300-ril/blob/master/atchannel.c" rel="noreferrer">ST-Ericsson 的 U300 RIL).

You can look at the code for atinout for an example for the is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess2 in ST-Ericsson's U300 RIL).

AT+CMGS 命令必须以不同方式处理.在发送有效载荷之前,您必须等待来自调制解调器的 " >" 响应,请参阅 这个答案 了解详情.

The AT+CMGS command must be handled differently. You must wait for the " > " response from the modem before sending the payload, see the first part of this answer for details.

1 尽管您很可能应该关心命令是否成功执行.请参阅此答案,了解发送命令行和解析响应行的实际方法.

1 Although you most likely should care about if the command was executed successfully or not. See this answer for a realistic way to send a command line and parse the response lines.

2 注意CONNECT不是最终结果码,是中间结果码,所以严格来说isFinalResponseSuccess这个名字不是100%正确的.

2 Note that CONNECT is not a final result code, it is an intermediate result code, so the name isFinalResponseSuccess is strictly speaking not 100% correct.

这篇关于无法使用 gsm 调制解调器使用 System.IO.Ports 通过 C# 代码发送短信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆