如何在C#中解析GSM调制解调器接收的SMS短信内容?
Hey there! Let's break down how to filter out irrelevant modem responses and extract the key SMS details (sender number, timestamp, message content) from the +CMT lines you're receiving.
Step 1: Filter Out Irrelevant Responses
First, you need to sift through all incoming serial data and ignore lines that don't relate to incoming SMS. That means skipping:
- AT command echoes (like
AT+CMGF=1orAT+CNMI=1,2,0,0,0) - Success/error acknowledgments (like
OK) - Any other lines that don't start with
+CMT:
In your SerialDataReceivedEventHandler method, read the incoming data line by line, and only process lines that match the +CMT: prefix.
Step 2: Parse the +CMT Line for Sender & Timestamp
The +CMT line follows a standard GSM format, which makes parsing straightforward. Let's use your example:
+CMT: "+xxxxxxxxxx",,"18/05/30,10:08:08+18"
Option 1: String Splitting (Simple Approach)
You can split the line using basic string operations to extract values:
// Example line from modem string cmtLine = "+CMT: \"+xxxxxxxxxx\",,\"18/05/30,10:08:08+18\""; // Remove the "+CMT: " prefix string contentPart = cmtLine.Substring(6).Trim(); // Split by the quoted separator to avoid breaking on commas inside values string[] parts = contentPart.Split(new[] { "\",," }, StringSplitOptions.None); string senderNumber = parts[0].Trim('"'); string timestampStr = parts[1].Trim('"');
Option 2: Regular Expression (More Robust)
For better handling of minor format variations, use a regex pattern to capture the sender and timestamp reliably:
using System.Text.RegularExpressions; using System.Globalization; string cmtPattern = @"\+CMT: ""(\+?\d+)"",,""(\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}\+\d{2})"""; Match match = Regex.Match(cmtLine, cmtPattern); if (match.Success) { string senderNumber = match.Groups[1].Value; string timestampStr = match.Groups[2].Value; // Convert timestamp to a DateTime object for database storage DateTime smsTimestamp = DateTime.ParseExact(timestampStr, "dd/MM/yy,HH:mm:sszzz", CultureInfo.InvariantCulture); }
Step 3: Extract the SMS Content
Right after the +CMT line, the next line(s) contain the actual SMS message content (like your example's Testing).
In your serial data handling, after identifying a +CMT line, read subsequent lines until you hit a non-content line (like another command response or the end of the data stream). Note that longer SMS might span multiple lines, so concatenate those lines if needed.
Step 4: Store to Database
Once you have the sender number, parsed timestamp, and message content, insert them into your database using your preferred data access method (EF Core, ADO.NET, etc.). Here's a quick pseudocode example:
// Pseudocode for database insertion using (var db = new MessengerDbContext()) { var incomingSms = new IncomingSms { SenderNumber = senderNumber, ReceivedAt = smsTimestamp, Content = messageContent }; db.IncomingSms.Add(incomingSms); db.SaveChanges(); }
Key Notes
- Handle encoding: GSM modems often use GSM 03.38 encoding for messages, so you may need to convert incoming text to UTF-8 if your database uses that standard.
- Edge cases: Watch for empty messages, messages with special characters, or slight timestamp format variations (some modems might use different time zone notations).
内容的提问来源于stack exchange,提问作者Daniel Žeimo

