First of all, I do not see any specific event handlers in the OnComm method. This method is not only called when the receivebuffer threshold has been reached. It is also called other times, like a change in the CTS line or something like that.
I once had the same problem as you now have, but it was financial information that I had to transmit, so it was crucial that all bytes arrived, without any corruption. I also only had the MSCOMM control at hand, so I wrote a protocol of my own (which, until so far, seems to work fine):
'Sender:
Private Function SendFileByModem(ByVal vsFile As String, ByVal vsCmd As String, Optional ByVal vbKillFile As Boolean = False) As Boolean
'Send a file to a remote system.
'
'vsFile : Full path and filename of source file.
'vsCmd : Command to be send to remote system, befor starting upload.
'vbKillFile: Specifies whether or not to kill the original file.
'
'Since we do not have a protocol available, made one up:
'* A header prefixes the contents of the file:
' - 1st byte represents size of this header (including this byte and checkbyte).
' - 2nd byte represents size of filename.
' - Then follow X characters which specify the name of the file being transfered.
' - Then follow X characters (1st byte - 1(2nd byte) - number of characters of the name - CheckByte) which represent the size of the file.
' - Then follows the checkbyte.
'* Then follow X transfers of 255 characters each (or less), including the prefix byte (which represent the number of characters to follow) and including checkbyte (last character).
'* When a block has been transfered, a footer follows:
' - 1st byte is size of footer (always 18).
' - Following bytes are ASCII characters "#XFER COMPLETED#".
' - Again a checkbyte.
'* The checkbyte is the exlusive or of all bytes of the block, including the length byte.
'* After EVERY block that has been received, the receiver has to answer with "XFEROK" & vbCr.
Dim lbOk As Boolean
Dim lnFileNr As Integer, lnBlockSize As Integer
Dim lnFileSize As Long, lnFilePointer As Long
Dim lsFile As String, lsData As String
Dim lobjMdm As MSComm
Set lobjMdm = frmMain.Modem
lbOk = True
ResetModemIdleTimer
lobjMdm.OutBufferCount = 0
lobjMdm.Output = vsCmd 'Tell recevier that we want to send a file.
If Synchronize() <> 0 Then 'Wait until receiver is ready.
lbOk = False
Else
lnFileSize = FileLen(vsFile)
lnFilePointer = 1
If lnFileSize > 0 Then 'Only if there is actually something to send.
'Send header:
lsData = Chr(1 + Len(CStr(lnFileSize)) + 1 + Len(RemovePath(vsFile)) + 1) 'Size of header.
lsData = lsData & Chr(Len(RemovePath(vsFile))) 'Length of filename.
lsData = lsData & RemovePath(vsFile) 'Filename.
lsData = lsData & CStr(lnFileSize) 'Filesize.
lsData = lsData & GetCheckByte(lsData) 'Add checkbyte.
lobjMdm.Output = lsData
If WaitReceiver() Then
'Send data:
lnFileNr = FreeFile
Open Trim$(vsFile) For Binary As #lnFileNr
While lnFilePointer <= lnFileSize
ResetModemIdleTimer
If lnFilePointer + 252 <= lnFileSize Then lnBlockSize = 253 Else lnBlockSize = lnFileSize - lnFilePointer + 1
lsData = Space(lnBlockSize) 'Number of bytes to send.
Get #lnFileNr, lnFilePointer, lsData
lnFilePointer = lnFilePointer + lnBlockSize
frmMain.MainModemStatus = "Sending " & RemovePath(vsFile) & " (" & Format(CSng(CSng(lnFilePointer - 1) / CSng(lnFileSize)) * 100, "0.00"

& " %)"
lsData = Chr(Len(lsData) + 2) & lsData 'Length of this block and filedata.
lsData = lsData & GetCheckByte(lsData) 'Checkbyte.
lobjMdm.Output = lsData
If Not WaitReceiver() Then
lnFilePointer = lnFileSize 'If not ok, then force halt.
lbOk = False
End If
Wend
Close #lnFileNr
If lbOk Then 'Ok, file has been send correctly.
'Send footer:
lsData = Chr(18) 'Length is always 18.
lsData = lsData & "#XFER COMPLETED#"
lsData = lsData & GetCheckByte(lsData)
lobjMdm.Output = lsData
If Not WaitReceiver() Then lbOk = False
End If
End If
End If
End If
If lbOk And vbKillFile Then Kill vsFile
SendFileByModem = lbOk
End Function
Private Function GetCheckByte(ByVal lsData As String) As String
Dim lnPos As Integer, lnByte As Integer
For lnPos = 1 To Len(lsData)
lnByte = lnByte Xor Asc(Mid(lsData, lnPos, 1))
Next lnPos
GetCheckByte = Chr(lnByte)
End Function
//
//The next method is a bit sloppy, but this is because it was an ancient system and it had to stay compatible....
Function Synchronize() As Integer
Dim n As Integer
Dim n2 As Single, e As Single
Dim strModem As String
Synchronize = 0
'Wait for the receiver to become ready...
n2 = Timer
e = n2 + 300
If e >= 86400 Then
e = e - 86400
End If
Do
If Not frmMain.Modem.CDHolding Then Synchronize = -1 'No carrier
If frmMain.Modem.InBufferCount = 7 Then 'Could be it...
strModem = UCase(StripControl(frmMain.Modem.Input))
If strModem = "RCV14" Then Exit Function 'Yes it is.
End If
If frmMain.Modem.InBufferCount = 8 Then 'Could be it...
strModem = frmMain.Modem.Input
strModem = UCase(StripControl(Mid$(strModem, 3)))
If strModem = "RCV14" Then Exit Function 'yes it is.
End If
DoEvents
Loop While e > Timer And Synchronize = 0
Synchronize = IIf((Synchronize = 0), -5, Synchronize) 'timeout or other problem ?
End Function
//
//Receiver (also a bit sloppy since this is really ancient (vb3):
Private Sub Modem_OnComm()
Dim lnFileNr As Integer
Select Case Modem.CommEvent
Case 3 'change in CTS
If DebugFlag Then Display Bonvenster, 0, "CTS " & Modem.CTSHolding
Case 4 'change in DSR
If DebugFlag Then Display Bonvenster, 0, "DSR " & Modem.DSRHolding
Case 5 'change in CD
If DebugFlag Then Display Bonvenster, 0, "CD " & Modem.CDHolding
If Not Modem.CDHolding Then 'No carrier
ModemIdle.Enabled = False 'stop modem idle timer.
Hangup 0 'autoanswer on
lnFileNr = FreeFile
Open Trim$(SysOptions.AppPath) & Trim$(SysOptions.AppName) & ".ERR" For Append As #lnFileNr
Print #lnFileNr, "****** Connection broken: " & Date$ & " / " & Time$
Close #lnFileNr
Else
ModemBusy = True
End If
Case 6 'ringing
If SysOptions.DatacomStatus = 2 Then 'auto answer allowed
Modem.InBufferCount = 0
Display Statusvenster, DatacomStatusregel, "Modem: " & TABCHAR & "Answering"
Modem.Output = "ATA" & Chr(13) 'beantwoord de oproep
lnFileNr = FreeFile
Open Trim$(SysOptions.AppPath) & Trim$(SysOptions.AppName) & ".ERR" For Append As #lnFileNr
Print #lnFileNr, "****** Start datacom: " & Date$ & " / " & Time$
Close #lnFileNr
gblnDatacom = True
ModemIdle.Interval = 60000
ModemIdle.Enabled = True 'start modem idle timer.
DoModemComm
End If
End Select
End Sub
Private Sub DoModemComm()
Dim lsRx As String, lsCmd As String
Do
DoEvents
If Modem.InBufferCount > 0 Then
'Reset idle timer:
ResetModemIdleTimer
'Add to data buffer:
lsRx = lsRx & Modem.Input
End If
If Len(lsRx) > 0 Then
If InStr(lsRx, Chr(13)) > 0 Then 'A command has been received.
lsCmd = StripControl(Trim$(Left$(lsRx, InStr(lsRx, Chr(13)) - 1)))
lsRx = Mid$(lsRx, InStr(lsRx, Chr(13)) + 1)
If DebugFlag = True And Len(lsCmd) > 0 Then Display BonVenster, 0, Left$(lsCmd, 20)
Debug.Print "<<Modem<< " & lsCmd
If Len(lsCmd) > 0 Then DoModemCmd lsCmd 'this is where a huge select case switches os to the next method
lsCmd = ""
End If
End If
Loop While gblnDataCom
End Sub
Private Sub DoReceiveImport()
Dim lnFileNr As Integer
Modem.Output = Chr$(13) & "RCV14" & Chr$(13) 'We're ready to receive data now.
While Modem.OutBufferCount > 0
DoEvents
Wend
GetFileByModem Trim$(SysOptions.AppPath) & "\import", ""
End Sub
Private Function GetFileByModem(ByVal vsDestPath As String, ByVal vsFileName As String) As Integer
Dim lnBlockSize As Integer, lnCheckSum As Integer, lnPos As Integer, lnFileNr As Integer
Dim lnFileSize As Long, lnReceived As Long
Dim lsData As String, lsOrgFile As String, lsDestFile As String, lsTemp As String
GetFileByModem = False
If Right(vsDestPath, 1) <> "\" Then vsDestPath = vsDestPath & "\"
Modem.OutBufferCount = 0
ResetModemIdleTimer
'First the header:
lnBlockSize = -1
lsData = ""
While (lnBlockSize <> Len(lsData)) And (ModemIdle.Enabled = True)
If Modem.InBufferCount > 0 Then
ResetModemIdleTimer
lsData = lsData & Modem.Input
If lnBlockSize = -1 Then lnBlockSize = Asc(Left(lsData, 1))
DoEvents
End If
Wend
'Process header:
If Not IsCheckSumOk(lsData) Then Exit Function
lsOrgFile = Mid(lsData, 3, Asc(Mid(lsData, 2, 1))) 'Original filename.
lnFileSize = Val(Mid(lsData, 3 + Len(lsOrgFile), Len(lsData) - 3 - Len(lsOrgFile))) 'Size in bytes of the file.
lsDestFile = vsDestPath & CStr(IIf(vsFileName <> "", vsFileName, lsOrgFile)) 'Destination.
Modem.Output = "XFEROK" & Chr(13) 'Ready to receive next part.
'Get file data and footer:
lnFileNr = FreeFile
lnReceived = 0
If CheckFileExists(lsDestFile) Then Kill lsDestFile
Open lsDestFile For Binary As #lnFileNr
Do While True
lnBlockSize = -1
lsData = ""
While (lnBlockSize <> Len(lsData)) And (ModemIdle.Enabled = True)
If Modem.InBufferCount > 0 Then
ResetModemIdleTimer
lsData = lsData & Modem.Input
If lnBlockSize = -1 Then lnBlockSize = Asc(Left(lsData, 1))
DoEvents
End If
Wend
'Process block:
If Not IsCheckSumOk(lsData) Then
Close #lnFileNr
lnFileNr = -1 'Force halt.
On Error Resume Next
Kill lsDestFile
On Error GoTo 0
Exit Do
End If
If lnBlockSize = 18 Then 'This might be the footer.
Select Case Mid(lsData, 2, 16)
Case "#XFER COMPLETED#": 'Done.
Close #lnFileNr
lnFileNr = -1 'Force halt.
Exit Do
Case Else: 'Ordinary data block.
lnReceived = lnReceived + Len(lsData) - 2
lsTemp = CStr(Mid(lsData, 2, 16))
Put #lnFileNr, , lsTemp
End Select
Else
lnReceived = lnReceived + Len(lsData) - 2
lsTemp = CStr(Mid(lsData, 2, Len(lsData) - 2))
Put #lnFileNr, , lsTemp
End If
Display StatusVenster, DatacomStatusRegel, "Modem:" & TabChar & "<< " & lsOrgFile & " (" & Format(CSng((CSng(lnReceived) / CSng(lnFileSize))) * 100, "0.00"

& "%)"
Modem.Output = "XFEROK" & Chr(13) 'Ready for next block.
Loop
Modem.Output = "XFEROK" & Chr(13) 'Done.
GetFileByModem = ModemIdle.Enabled
End Function
Private Function IsCheckSumOk(ByVal vsData As String) As Integer
Dim lnPos As Integer, lnCheck As Integer, lnFileNr As Integer
For lnPos = 1 To Len(vsData) - 1
lnCheck = lnCheck Xor Asc(Mid(vsData, lnPos, 1))
Next lnPos
If Not (lnCheck = Asc(Right(vsData, 1))) Then
lnFileNr = FreeFile
Open Trim$(SysOptions.AppPath) & Trim$(SysOptions.AppName) & ".ERR" For Append As lnFileNr
Print #lnFileNr, "!!!!!! Checksum error: " & Date$ & "/ " & Time$
Close #lnFileNr
IsCheckSumOk = False
Else
IsCheckSumOk = True
End If
End Function
As you can see, we did more than just sending files and also we used a modem. But stripping those parts should lead to a fairly stable way of transmitting data.
Rum am Morgen vorkommt Kummer und Sorgen... Cheers !
Mr. Rum