无法使用gsm调制解调器使用System.IO.Ports通过C#代码发送SMS

时间:2015-10-20 10:57:43

标签: c# sms gsm at-command modem

单击一个按钮,会将短信发送到NumTxt文本框中输入的数字,并发送在SMSTxt文本框中输入的文本。在texbox ComPort中输入的端口名称这是按钮点击事件的事件处理程序。

  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调制解调器附带的软件时,我可以发送短信。但不是通过C#代码。如果有人能够在上面的代码中指出错误,我将非常感激。

1 个答案:

答案 0 :(得分:3)

你应该从不,永远不会使用sleep来代替等待调制解调器的最终结果代码。正如您不会编写完全忽略来自http服务器的所有响应的http客户端一样,您不应将AT命令发送到调制解调器并完全忽略它发回的响应。您必须读取并解析调制解调器发回给您的所有内容。没有别的东西能可靠地运作。

我的建议是,您首先要获取V.250 standard的副本,并至少阅读第5章的全部内容。此标准是AT命令处理的圣经,并将教您大量有关AT命令处理的内容。例如,使用WriteLine和/或Environment.NewLine是错误的; AT命令行应该单独使用\r终止,而不是其他任何内容。

只是强调文档的重要性:即使在爱立信手机中实施AT命令十多年之后,我和我的同事仍然consulted that standard regularly

事实上,现在停止阅读这个答案,download该文件,在返回阅读其余部分之前阅读第5章的所有内容。

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

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

其中readLine函数从串行端口读取一个和一个字节,直到它收到以\r\n终止的完整行,然后返回该行。

您可以查看atinout的代码,了解is_final_result_code函数的示例(您还可以与isFinalResponseErrorisFinalResponseSuccess 2 在ST-Ericsson's U300 RIL)。

必须以不同方式处理AT + CMGS命令。您必须在发送有效负载之前等待来自调制解调器的"\r\n> "响应,有关详细信息,请参阅this answer的第一部分。

1 虽然您很可能应该关心命令是否成功执行。有关发送命令行和解析响应行的实际方法,请参阅this answer

2 请注意CONNECT不是最终结果代码,它是一个中间结果代码,所以名称isFinalResponseSuccess严格来说不是100%正确。