If you use SimpleSock or SimpleServer, I have found a more efficient and faster way to receive sockets when using a fixed record header. TLS 1.3 encrypted records for example use a fixed 5 byte header.
It uses a function that was built into these routines that allows a specific number of bytes to be recovered from the Winsock buffer. There was however a bug in SimpleSock that prevented this function from working properly. SimpleServer did not exhibit the same problem, so the SimpleSock download has been updated at:
https://www.vbforums.com/showthread....B6-Simple-Sock
The problem code was in the BuildArray Function.
Previously, the buffer was managed in the calling function using static variables and self contained buffers:
Using the class buffer instead, we extract the header, recover the record length, and then wait for the full record to be accumulated in the class buffer. There is no danger of overflowing the class buffer because it is self regulating.
Using TLS, record lengths are limited, but if you are streaming large records using this technique, you should make "RecLen" static, and process bytes as they are received. This can usually be accomplished by using the SendComplete routine and comparing the total bytes received to RecLen.
J.A. Coutts
Code:
TLSHeader(0) = RecType
TLSHeader(1) = VERSION_MAJOR
TLSHeader(2) = VERSION_MINOR_3
TLSHeader(3) = Reclen (high byte)
TLSHeader(4) = RecLen (low byte)
https://www.vbforums.com/showthread....B6-Simple-Sock
The problem code was in the BuildArray Function.
Code:
If m_Protocol = SCK_TCP Then 'TCP transfers data from m_bRecvBuffer
BuildArray = m_bRecvBuffer 'lSize
If Not blnPeek Then
Call DeleteByte(m_bRecvBuffer, lSize)
End If
was changed to:
If m_Protocol = SCK_TCP Then 'TCP transfers data from m_bRecvBuffer
ReDim bTmp(lSize - 1)
CopyMemory bTmp(0), m_bRecvBuffer(0), lSize
BuildArray = bTmp
If Not blnPeek Then
Call DeleteByte(m_bRecvBuffer, lSize)
End If
Code:
Private Sub mClient_EncrDataArrival(ByVal bytesTotal As Long)
Dim bData() As Byte
'This routine is re-entrant, hence the next 3 variables must be static
Static InBuff() As Byte
Static Header() As Byte
Static RecLen As Long
Call mClient.RecoverData
bData = mClient.bInBuffer
Call AddByte(InBuff, bData) 'Add data to buffer
GetNextRecord:
If GetbSize(InBuff) < 5 Then Exit Sub 'If no record length yet then exit & wait
If RecLen = 0 Then 'New record
ReDim Header(4)
CopyMemory Header(0), InBuff(0), 5 'Save Header
Call DeleteByte(InBuff, 5) 'Remove Header from buffer
RecLen = CLng(Header(3)) * 256 + Header(4) 'Calculate record length
Select Case Header(0)
Case 1, 2, 4, 5, 6, 8, 9, 16
'Record type OK
Case Else 'Ignore record
Call DeleteByte(InBuff, RecLen)
GoTo Done
End Select
End If
If GetbSize(InBuff) >= RecLen Then 'Complete record available
ReDim bData(RecLen - 1) 'Resize buffer to record length
CopyMemory bData(0), InBuff(0), RecLen 'Copy record data to buffer
Call DeleteByte(InBuff, RecLen) 'Delete record data from inbuff
Crypt.InBuffer = bData 'Save record to encryption InBuffer
Else
Exit Sub 'Wait for complete record
End If
'record complete - Process it
....
....
....
Done:
RecLen = 0
ReDim Header(0)
If GetbSize(InBuff) > 0 Then GoTo GetNextRecord
End Sub
Code:
Private Sub mClient_EncrDataArrival(ByVal bytesTotal As Long)
Dim bRecord() As Byte
Dim Header() As Byte
Dim RecLen As Long
GetNextRecord:
If RecLen = 0 Then 'Remove header
If bytesTotal < 5 Then Exit Sub 'If no record length yet then exit & wait
mClient.RecoverData 5
Header = mClient.bInBuffer
Call DebugPrintByte("Header", Header)
RecLen = CLng(Header(3)) * 256 + Header(4)
bytesTotal = bytesTotal - 5
End If
If RecLen = 0 Then 'Invalid record
'Do nothing
ElseIf bytesTotal >= RecLen Then
mClient.RecoverData RecLen
bRecord = mClient.bInBuffer
bytesTotal = bytesTotal - RecLen
Crypt.InBuffer = bRecord
'record complete - Process it
....
....
....
Done:
RecLen = 0
If bytesTotal > 0 Then GoTo GetNextRecord
Else
'Wait for all the data
End If
End Sub
J.A. Coutts