This code is rather old (2005) and part of a bigger multithreaded app. I cut out pieces of the code and pasted below. The code will not run as it is but may give you an idea. I would write it quite differently today but with the same concept of a buffer holding all received data. Also some carriers allow you to send emails through SMS so I included that sub routine as well.
Private strPort As String = String.Empty
Private WithEvents sp As SerialPort
Private strBuffer As String = String.Empty
Private Delegate Sub UpdateBufferDelegate(ByVal Text As String)
Public Sub SendTextMessage(ByVal [To] As String, ByVal Message As String)
sp = My.Computer.Ports.OpenSerialPort(strPort)
SendData("ATZ" & vbCr, "OK")
SendData("AT+CMGF=1" & vbCr, "OK")
SendData("AT+CMGS=" & Chr(34) & [To] & Chr(34) & vbCr, ">")
SendData(Message & vbCr, ">")
SendData(Chr(26), "OK")
sp.Close()
End Sub
Public Sub SendEmail(ByVal [To] As String, ByVal Subject As String, ByVal Body As String)
sp = My.Computer.Ports.OpenSerialPort(strPort)
SendData("ATZ" & vbCr, "OK")
SendData("AT+CMGF=1" & vbCr, "OK")
SendData("AT+CMGS=" & Chr(34) & "500" & Chr(34) & vbCr, ">")
SendData([To] & " " & Subject & "# " & Body & vbCr, ">")
SendData(Chr(26), "OK")
sp.Close()
End Sub
' Send data without waiting for specific response
Private Sub SendData(ByVal Data As String)
sp.Write(Data)
End Sub
' Send data and wait for a specific response
Private Sub SendData(ByVal Data As String, ByVal WaitFor As String)
sp.Write(Data)
WaitForData(WaitFor)
End Sub
Private Function WaitForData(ByVal Data As String, Optional ByVal Timeout As Integer = 10) As Boolean
Dim StartTime As Date = Date.Now
Do
If InStr(strBuffer, Data) > 0 Then
strBuffer = strBuffer.Substring((InStr(strBuffer, Data) - 1) + Data.Length)
Return True
End If
If Date.Now.Subtract(StartTime).TotalSeconds >= Timeout Then
Return False
End If
Loop
End Function
Private Sub UpdateBuffer(ByVal Text As String)
strBuffer &= Text
End Sub
Private Sub sp_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles sp.DataReceived
Dim dUpdateBuffer As New UpdateBufferDelegate(AddressOf UpdateBuffer)
Dim strTmp As String = sp.ReadExisting
dUpdateBuffer.Invoke(strTmp)
End Sub