<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://groupkos.com/dev/index.php?action=history&amp;feed=atom&amp;title=Robust_Winsock_VB6_Class</id>
	<title>Robust Winsock VB6 Class - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://groupkos.com/dev/index.php?action=history&amp;feed=atom&amp;title=Robust_Winsock_VB6_Class"/>
	<link rel="alternate" type="text/html" href="http://groupkos.com/dev/index.php?title=Robust_Winsock_VB6_Class&amp;action=history"/>
	<updated>2026-04-21T13:10:54Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>http://groupkos.com/dev/index.php?title=Robust_Winsock_VB6_Class&amp;diff=5040&amp;oldid=prev</id>
		<title>XenoEngineer at 22:46, 15 April 2025</title>
		<link rel="alternate" type="text/html" href="http://groupkos.com/dev/index.php?title=Robust_Winsock_VB6_Class&amp;diff=5040&amp;oldid=prev"/>
		<updated>2025-04-15T22:46:38Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:46, 15 April 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:VB6]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:socket]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;background-color:azure; border:1px outset azure; padding:0 20px; max-width:860px; margin:0 auto; &amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;background-color:azure; border:1px outset azure; padding:0 20px; max-width:860px; margin:0 auto; &amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;;* https://claude.site/artifacts/d8b8157d-7faa-4125-b1cf-50108a4a2cb0&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;;* https://claude.site/artifacts/d8b8157d-7faa-4125-b1cf-50108a4a2cb0&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>XenoEngineer</name></author>
	</entry>
	<entry>
		<id>http://groupkos.com/dev/index.php?title=Robust_Winsock_VB6_Class&amp;diff=5039&amp;oldid=prev</id>
		<title>XenoEngineer: Created page with &quot;&lt;div style=&quot;background-color:azure; border:1px outset azure; padding:0 20px; max-width:860px; margin:0 auto; &quot;&gt; ;* https://claude.site/artifacts/d8b8157d-7faa-4125-b1cf-50108a4a2cb0 &lt;pre style=&quot;margin-left:3em; font:normal 14px terminal;&quot;&gt;  Option Explicit  &#039; RobustWinsock Class &#039; A robust VB6 winsock implementation designed to handle large data transfers, &#039; connection failures, and error recovery. &#039; &#039; Features: &#039; - Automatic reconnection on failure &#039; - Chunked data tran...&quot;</title>
		<link rel="alternate" type="text/html" href="http://groupkos.com/dev/index.php?title=Robust_Winsock_VB6_Class&amp;diff=5039&amp;oldid=prev"/>
		<updated>2025-04-14T16:24:49Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;div style=&amp;quot;background-color:azure; border:1px outset azure; padding:0 20px; max-width:860px; margin:0 auto; &amp;quot;&amp;gt; ;* https://claude.site/artifacts/d8b8157d-7faa-4125-b1cf-50108a4a2cb0 &amp;lt;pre style=&amp;quot;margin-left:3em; font:normal 14px terminal;&amp;quot;&amp;gt;  Option Explicit  &amp;#039; RobustWinsock Class &amp;#039; A robust VB6 winsock implementation designed to handle large data transfers, &amp;#039; connection failures, and error recovery. &amp;#039; &amp;#039; Features: &amp;#039; - Automatic reconnection on failure &amp;#039; - Chunked data tran...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;background-color:azure; border:1px outset azure; padding:0 20px; max-width:860px; margin:0 auto; &amp;quot;&amp;gt;&lt;br /&gt;
;* https://claude.site/artifacts/d8b8157d-7faa-4125-b1cf-50108a4a2cb0&lt;br /&gt;
&amp;lt;pre style=&amp;quot;margin-left:3em; font:normal 14px terminal;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Option Explicit&lt;br /&gt;
&lt;br /&gt;
&amp;#039; RobustWinsock Class&lt;br /&gt;
&amp;#039; A robust VB6 winsock implementation designed to handle large data transfers,&lt;br /&gt;
&amp;#039; connection failures, and error recovery.&lt;br /&gt;
&amp;#039;&lt;br /&gt;
&amp;#039; Features:&lt;br /&gt;
&amp;#039; - Automatic reconnection on failure&lt;br /&gt;
&amp;#039; - Chunked data transfer for large files&lt;br /&gt;
&amp;#039; - Timeout handling&lt;br /&gt;
&amp;#039; - CRC checking for data integrity&lt;br /&gt;
&amp;#039; - Session management&lt;br /&gt;
&amp;#039; - Event-based architecture&lt;br /&gt;
&amp;#039; - Comprehensive error handling&lt;br /&gt;
&amp;#039; - Buffer management for large transfers&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Constants for socket states&lt;br /&gt;
Private Const SOCKET_CLOSED = 0&lt;br /&gt;
Private Const SOCKET_OPEN = 1&lt;br /&gt;
Private Const SOCKET_LISTENING = 2&lt;br /&gt;
Private Const SOCKET_CONNECTION_PENDING = 3&lt;br /&gt;
Private Const SOCKET_RESOLVING_HOST = 4&lt;br /&gt;
Private Const SOCKET_HOST_RESOLVED = 5&lt;br /&gt;
Private Const SOCKET_CONNECTING = 6&lt;br /&gt;
Private Const SOCKET_CONNECTED = 7&lt;br /&gt;
Private Const SOCKET_CLOSING = 8&lt;br /&gt;
Private Const SOCKET_ERROR = 9&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Constants for CRC calculation&lt;br /&gt;
Private Const CRC32_POLYNOMIAL = &amp;amp;HEDB88320&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Constants for error handling&lt;br /&gt;
Private Const ERR_WINSOCK_BASE = 10000&lt;br /&gt;
Private Const ERR_CONNECTION_TIMEOUT = ERR_WINSOCK_BASE + 1&lt;br /&gt;
Private Const ERR_CONNECTION_RESET = ERR_WINSOCK_BASE + 2&lt;br /&gt;
Private Const ERR_DATA_INTEGRITY = ERR_WINSOCK_BASE + 3&lt;br /&gt;
Private Const ERR_BUFFER_OVERFLOW = ERR_WINSOCK_BASE + 4&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Constants for data transfer&lt;br /&gt;
Private Const DEFAULT_BUFFER_SIZE = 8192      &amp;#039; 8KB default buffer&lt;br /&gt;
Private Const MAX_BUFFER_SIZE = 1048576       &amp;#039; 1MB max buffer&lt;br /&gt;
Private Const DEFAULT_TIMEOUT = 30000         &amp;#039; 30 seconds&lt;br /&gt;
Private Const DEFAULT_RETRY_COUNT = 3         &amp;#039; Default number of retries&lt;br /&gt;
Private Const DEFAULT_HEARTBEAT_INTERVAL = 5000 &amp;#039; 5 seconds&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Member variables&lt;br /&gt;
Private m_Winsock As Winsock               &amp;#039; The actual Winsock control&lt;br /&gt;
Private m_BufferSize As Long               &amp;#039; Size of the buffer&lt;br /&gt;
Private m_SendBuffer() As Byte             &amp;#039; Buffer for sending data&lt;br /&gt;
Private m_ReceiveBuffer() As Byte          &amp;#039; Buffer for receiving data&lt;br /&gt;
Private m_SendBufferLength As Long         &amp;#039; Current length of send buffer&lt;br /&gt;
Private m_ReceiveBufferLength As Long      &amp;#039; Current length of receive buffer&lt;br /&gt;
Private m_Timeout As Long                  &amp;#039; Timeout in milliseconds&lt;br /&gt;
Private m_RetryCount As Integer            &amp;#039; Number of retries&lt;br /&gt;
Private m_CurrentRetry As Integer          &amp;#039; Current retry count&lt;br /&gt;
Private m_RemoteHost As String             &amp;#039; Remote host name or IP&lt;br /&gt;
Private m_RemotePort As Long               &amp;#039; Remote port&lt;br /&gt;
Private m_LocalPort As Long                &amp;#039; Local port&lt;br /&gt;
Private m_Connected As Boolean             &amp;#039; Connection state&lt;br /&gt;
Private m_LastError As Long                &amp;#039; Last error code&lt;br /&gt;
Private m_LastErrorMessage As String       &amp;#039; Last error message&lt;br /&gt;
Private m_AutoReconnect As Boolean         &amp;#039; Auto reconnect flag&lt;br /&gt;
Private m_HeartbeatTimer As Timer          &amp;#039; Timer for heartbeats&lt;br /&gt;
Private m_HeartbeatInterval As Long        &amp;#039; Heartbeat interval&lt;br /&gt;
Private m_TransferInProgress As Boolean    &amp;#039; Flag for transfer in progress&lt;br /&gt;
Private m_TotalBytesSent As Long           &amp;#039; Total bytes sent in current transfer&lt;br /&gt;
Private m_TotalBytesReceived As Long       &amp;#039; Total bytes received in current transfer&lt;br /&gt;
Private m_ConnectionTimer As Timer         &amp;#039; Timer for connection timeout&lt;br /&gt;
Private m_SessionID As String              &amp;#039; Unique session identifier&lt;br /&gt;
Private m_CRCTable(0 To 255) As Long       &amp;#039; Table for CRC calculation&lt;br /&gt;
Private m_TransferID As Long               &amp;#039; Current transfer ID&lt;br /&gt;
Private m_ChunkSize As Long                &amp;#039; Size of data chunks&lt;br /&gt;
Private m_PacketSequence As Long           &amp;#039; Packet sequence number&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Event declarations&lt;br /&gt;
Public Event Connected()&lt;br /&gt;
Public Event Disconnected()&lt;br /&gt;
Public Event DataArrival(ByVal bytesTotal As Long)&lt;br /&gt;
Public Event SendComplete()&lt;br /&gt;
Public Event Error(ByVal Number As Long, ByVal Description As String)&lt;br /&gt;
Public Event ConnectionRequest(ByVal requestID As Long)&lt;br /&gt;
Public Event ProgressUpdate(ByVal bytesSent As Long, ByVal bytesTotal As Long)&lt;br /&gt;
Public Event TransferComplete(ByVal transferID As Long, ByVal success As Boolean)&lt;br /&gt;
Public Event Timeout()&lt;br /&gt;
Public Event Reconnecting(ByVal attemptNumber As Integer)&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Class initialization&lt;br /&gt;
Private Sub Class_Initialize()&lt;br /&gt;
    &amp;#039; Initialize default values&lt;br /&gt;
    m_BufferSize = DEFAULT_BUFFER_SIZE&lt;br /&gt;
    m_Timeout = DEFAULT_TIMEOUT&lt;br /&gt;
    m_RetryCount = DEFAULT_RETRY_COUNT&lt;br /&gt;
    m_CurrentRetry = 0&lt;br /&gt;
    m_Connected = False&lt;br /&gt;
    m_AutoReconnect = True&lt;br /&gt;
    m_HeartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL&lt;br /&gt;
    m_TransferInProgress = False&lt;br /&gt;
    m_TotalBytesSent = 0&lt;br /&gt;
    m_TotalBytesReceived = 0&lt;br /&gt;
    m_ChunkSize = DEFAULT_BUFFER_SIZE&lt;br /&gt;
    m_PacketSequence = 0&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Initialize buffers&lt;br /&gt;
    ReDim m_SendBuffer(0 To m_BufferSize - 1)&lt;br /&gt;
    ReDim m_ReceiveBuffer(0 To m_BufferSize - 1)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Create a unique session ID&lt;br /&gt;
    m_SessionID = GenerateSessionID()&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Initialize CRC table&lt;br /&gt;
    InitializeCRCTable&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Create the Winsock control&lt;br /&gt;
    Set m_Winsock = New Winsock&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Set up timers&lt;br /&gt;
    Set m_HeartbeatTimer = New Timer&lt;br /&gt;
    m_HeartbeatTimer.Interval = m_HeartbeatInterval&lt;br /&gt;
    m_HeartbeatTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    Set m_ConnectionTimer = New Timer&lt;br /&gt;
    m_ConnectionTimer.Interval = m_Timeout&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Class termination&lt;br /&gt;
Private Sub Class_Terminate()&lt;br /&gt;
    &amp;#039; Clean up&lt;br /&gt;
    If m_Connected Then&lt;br /&gt;
        DisconnectSocket&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Stop timers&lt;br /&gt;
    m_HeartbeatTimer.Enabled = False&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Clean up objects&lt;br /&gt;
    Set m_Winsock = Nothing&lt;br /&gt;
    Set m_HeartbeatTimer = Nothing&lt;br /&gt;
    Set m_ConnectionTimer = Nothing&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Initialize the CRC table for data integrity checks&lt;br /&gt;
Private Sub InitializeCRCTable()&lt;br /&gt;
    Dim i As Long, j As Long, crc As Long&lt;br /&gt;
    &lt;br /&gt;
    For i = 0 To 255&lt;br /&gt;
        crc = i&lt;br /&gt;
        For j = 0 To 7&lt;br /&gt;
            If (crc And 1) Then&lt;br /&gt;
                crc = (crc \ 2) Xor CRC32_POLYNOMIAL&lt;br /&gt;
            Else&lt;br /&gt;
                crc = crc \ 2&lt;br /&gt;
            End If&lt;br /&gt;
        Next j&lt;br /&gt;
        m_CRCTable(i) = crc&lt;br /&gt;
    Next i&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Calculate CRC32 for data integrity&lt;br /&gt;
Private Function CalculateCRC32(data() As Byte, ByVal length As Long) As Long&lt;br /&gt;
    Dim crc As Long, i As Long&lt;br /&gt;
    &lt;br /&gt;
    crc = &amp;amp;HFFFFFFFF&lt;br /&gt;
    &lt;br /&gt;
    For i = 0 To length - 1&lt;br /&gt;
        crc = ((crc \ 256) And &amp;amp;HFFFFFF) Xor m_CRCTable((crc And &amp;amp;HFF) Xor data(i))&lt;br /&gt;
    Next i&lt;br /&gt;
    &lt;br /&gt;
    CalculateCRC32 = Not crc&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Generate a unique session ID&lt;br /&gt;
Private Function GenerateSessionID() As String&lt;br /&gt;
    Dim guid As String&lt;br /&gt;
    guid = Format$(Now, &amp;quot;yyyymmddhhnnss&amp;quot;) &amp;amp; Format$(Timer, &amp;quot;000000&amp;quot;) &amp;amp; Format$(Rnd() * 1000000, &amp;quot;000000&amp;quot;)&lt;br /&gt;
    GenerateSessionID = guid&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Connect to a remote host&lt;br /&gt;
Public Function Connect(ByVal remoteHost As String, ByVal remotePort As Long) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Store connection parameters&lt;br /&gt;
    m_RemoteHost = remoteHost&lt;br /&gt;
    m_RemotePort = remotePort&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset counters&lt;br /&gt;
    m_CurrentRetry = 0&lt;br /&gt;
    m_TotalBytesSent = 0&lt;br /&gt;
    m_TotalBytesReceived = 0&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Attempt to connect&lt;br /&gt;
    AttemptConnection&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Start connection timeout timer&lt;br /&gt;
    m_ConnectionTimer.Enabled = True&lt;br /&gt;
    &lt;br /&gt;
    Connect = True&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    Connect = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Internal connection attempt&lt;br /&gt;
Private Sub AttemptConnection()&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Close any existing connection&lt;br /&gt;
    If m_Connected Then&lt;br /&gt;
        DisconnectSocket&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Attempt to connect&lt;br /&gt;
    m_Winsock.Connect m_RemoteHost, m_RemotePort&lt;br /&gt;
    &lt;br /&gt;
    Exit Sub&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Handle connection failure with retry&lt;br /&gt;
    If m_AutoReconnect And m_CurrentRetry &amp;lt; m_RetryCount Then&lt;br /&gt;
        m_CurrentRetry = m_CurrentRetry + 1&lt;br /&gt;
        RaiseEvent Reconnecting(m_CurrentRetry)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Wait a bit before retrying (exponential backoff)&lt;br /&gt;
        Dim waitTime As Long&lt;br /&gt;
        waitTime = 1000 * (2 ^ m_CurrentRetry)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Use a timer to retry&lt;br /&gt;
        Dim retryTimer As Timer&lt;br /&gt;
        Set retryTimer = New Timer&lt;br /&gt;
        retryTimer.Interval = waitTime&lt;br /&gt;
        retryTimer.Enabled = True&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Retry after wait&lt;br /&gt;
        AttemptConnection&lt;br /&gt;
    Else&lt;br /&gt;
        &amp;#039; Failed after all retries&lt;br /&gt;
        RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Listen for incoming connections&lt;br /&gt;
Public Function Listen(ByVal localPort As Long) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Store local port&lt;br /&gt;
    m_LocalPort = localPort&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Close any existing connection&lt;br /&gt;
    If m_Connected Then&lt;br /&gt;
        DisconnectSocket&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Start listening&lt;br /&gt;
    m_Winsock.LocalPort = localPort&lt;br /&gt;
    m_Winsock.Listen&lt;br /&gt;
    &lt;br /&gt;
    Listen = True&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    Listen = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Accept an incoming connection&lt;br /&gt;
Public Function Accept(ByVal requestID As Long) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Accept the connection&lt;br /&gt;
    m_Winsock.Accept requestID&lt;br /&gt;
    m_Connected = True&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Start heartbeat timer&lt;br /&gt;
    m_HeartbeatTimer.Enabled = True&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Stop connection timeout timer&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Raise connected event&lt;br /&gt;
    RaiseEvent Connected&lt;br /&gt;
    &lt;br /&gt;
    Accept = True&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    Accept = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Disconnect from the remote host&lt;br /&gt;
Public Sub Disconnect()&lt;br /&gt;
    On Error Resume Next&lt;br /&gt;
    &lt;br /&gt;
    DisconnectSocket&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Raise disconnected event&lt;br /&gt;
    RaiseEvent Disconnected&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Internal disconnect method&lt;br /&gt;
Private Sub DisconnectSocket()&lt;br /&gt;
    On Error Resume Next&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Close the socket&lt;br /&gt;
    If m_Winsock.State &amp;lt;&amp;gt; SOCKET_CLOSED Then&lt;br /&gt;
        m_Winsock.Close&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset connection state&lt;br /&gt;
    m_Connected = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Stop timers&lt;br /&gt;
    m_HeartbeatTimer.Enabled = False&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset buffers&lt;br /&gt;
    m_SendBufferLength = 0&lt;br /&gt;
    m_ReceiveBufferLength = 0&lt;br /&gt;
    m_TransferInProgress = False&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Send data over the connection&lt;br /&gt;
Public Function SendData(data() As Byte, ByVal length As Long) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if connected&lt;br /&gt;
    If Not m_Connected Then&lt;br /&gt;
        m_LastError = ERR_WINSOCK_BASE&lt;br /&gt;
        m_LastErrorMessage = &amp;quot;Not connected&amp;quot;&lt;br /&gt;
        RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
        SendData = False&lt;br /&gt;
        Exit Function&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Initialize transfer&lt;br /&gt;
    m_TransferInProgress = True&lt;br /&gt;
    m_TotalBytesSent = 0&lt;br /&gt;
    m_TransferID = CLng(Timer * 1000) &amp;#039; Create a unique transfer ID&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Send data in chunks for large transfers&lt;br /&gt;
    Dim remainingBytes As Long, currentChunk As Long, i As Long&lt;br /&gt;
    Dim sendBuffer() As Byte, headerBuffer(0 To 15) As Byte&lt;br /&gt;
    Dim crc As Long&lt;br /&gt;
    &lt;br /&gt;
    remainingBytes = length&lt;br /&gt;
    i = 0&lt;br /&gt;
    &lt;br /&gt;
    Do While remainingBytes &amp;gt; 0&lt;br /&gt;
        &amp;#039; Determine chunk size&lt;br /&gt;
        currentChunk = IIf(remainingBytes &amp;gt; m_ChunkSize, m_ChunkSize, remainingBytes)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Prepare chunk buffer&lt;br /&gt;
        ReDim sendBuffer(0 To currentChunk - 1)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Copy data to chunk buffer&lt;br /&gt;
        CopyMemory sendBuffer(0), data(i), currentChunk&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Calculate CRC for this chunk&lt;br /&gt;
        crc = CalculateCRC32(sendBuffer, currentChunk)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Create packet header&lt;br /&gt;
        &amp;#039; Format: [SessionID(8)][TransferID(4)][SequenceNumber(2)][Length(2)][CRC(4)]&lt;br /&gt;
        m_PacketSequence = m_PacketSequence + 1&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Prepare packet header&lt;br /&gt;
        ReDim headerBuffer(0 To 19)&lt;br /&gt;
        CopyMemory headerBuffer(0), CLng(m_TransferID), 4&lt;br /&gt;
        CopyMemory headerBuffer(4), CInt(m_PacketSequence), 2&lt;br /&gt;
        CopyMemory headerBuffer(6), CInt(currentChunk), 2&lt;br /&gt;
        CopyMemory headerBuffer(8), CLng(crc), 4&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Send header&lt;br /&gt;
        m_Winsock.SendData headerBuffer&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Small delay to ensure header is sent&lt;br /&gt;
        Sleep 10&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Send data chunk&lt;br /&gt;
        m_Winsock.SendData sendBuffer&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Update counters&lt;br /&gt;
        m_TotalBytesSent = m_TotalBytesSent + currentChunk&lt;br /&gt;
        remainingBytes = remainingBytes - currentChunk&lt;br /&gt;
        i = i + currentChunk&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Raise progress event&lt;br /&gt;
        RaiseEvent ProgressUpdate(m_TotalBytesSent, length)&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Small delay between chunks to prevent buffer overflow&lt;br /&gt;
        If remainingBytes &amp;gt; 0 Then Sleep 50&lt;br /&gt;
    Loop&lt;br /&gt;
    &lt;br /&gt;
    SendData = True&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    m_TransferInProgress = False&lt;br /&gt;
    SendData = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Send a string over the connection&lt;br /&gt;
Public Function SendString(ByVal strData As String) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Convert string to byte array&lt;br /&gt;
    Dim dataBytes() As Byte&lt;br /&gt;
    Dim length As Long&lt;br /&gt;
    &lt;br /&gt;
    length = Len(strData)&lt;br /&gt;
    ReDim dataBytes(0 To length - 1)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Copy string to byte array&lt;br /&gt;
    CopyMemory dataBytes(0), ByVal strData, length&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Send the data&lt;br /&gt;
    SendString = SendData(dataBytes, length)&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    SendString = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Send a file over the connection&lt;br /&gt;
Public Function SendFile(ByVal filePath As String) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if file exists&lt;br /&gt;
    If Not FileExists(filePath) Then&lt;br /&gt;
        m_LastError = ERR_WINSOCK_BASE&lt;br /&gt;
        m_LastErrorMessage = &amp;quot;File not found: &amp;quot; &amp;amp; filePath&lt;br /&gt;
        RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
        SendFile = False&lt;br /&gt;
        Exit Function&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Open the file&lt;br /&gt;
    Dim fileNum As Integer&lt;br /&gt;
    Dim fileLength As Long&lt;br /&gt;
    Dim buffer() As Byte&lt;br /&gt;
    Dim bytesRead As Long&lt;br /&gt;
    &lt;br /&gt;
    fileNum = FreeFile&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Get file size&lt;br /&gt;
    fileLength = FileLen(filePath)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Prepare buffer for file data&lt;br /&gt;
    ReDim buffer(0 To fileLength - 1)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Read file into buffer&lt;br /&gt;
    Open filePath For Binary Access Read As #fileNum&lt;br /&gt;
    Get #fileNum, , buffer&lt;br /&gt;
    Close #fileNum&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Send the file data&lt;br /&gt;
    SendFile = SendData(buffer, fileLength)&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    &amp;#039; Close file if open&lt;br /&gt;
    If fileNum &amp;gt; 0 Then&lt;br /&gt;
        Close #fileNum&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    SendFile = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Check if a file exists&lt;br /&gt;
Private Function FileExists(ByVal filePath As String) As Boolean&lt;br /&gt;
    On Error Resume Next&lt;br /&gt;
    FileExists = (Dir(filePath) &amp;lt;&amp;gt; &amp;quot;&amp;quot;)&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Get data from the receive buffer&lt;br /&gt;
Public Function GetData(ByRef data() As Byte, ByVal maxLength As Long) As Long&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if there&amp;#039;s data in the buffer&lt;br /&gt;
    If m_ReceiveBufferLength = 0 Then&lt;br /&gt;
        GetData = 0&lt;br /&gt;
        Exit Function&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Determine how much data to copy&lt;br /&gt;
    Dim copyLength As Long&lt;br /&gt;
    copyLength = IIf(m_ReceiveBufferLength &amp;gt; maxLength, maxLength, m_ReceiveBufferLength)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Resize the output buffer&lt;br /&gt;
    ReDim data(0 To copyLength - 1)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Copy data from receive buffer&lt;br /&gt;
    CopyMemory data(0), m_ReceiveBuffer(0), copyLength&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Shift remaining data in buffer&lt;br /&gt;
    If copyLength &amp;lt; m_ReceiveBufferLength Then&lt;br /&gt;
        CopyMemory m_ReceiveBuffer(0), m_ReceiveBuffer(copyLength), m_ReceiveBufferLength - copyLength&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Update buffer length&lt;br /&gt;
    m_ReceiveBufferLength = m_ReceiveBufferLength - copyLength&lt;br /&gt;
    &lt;br /&gt;
    GetData = copyLength&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    GetData = 0&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Get all available data as a string&lt;br /&gt;
Public Function GetString() As String&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if there&amp;#039;s data in the buffer&lt;br /&gt;
    If m_ReceiveBufferLength = 0 Then&lt;br /&gt;
        GetString = &amp;quot;&amp;quot;&lt;br /&gt;
        Exit Function&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Convert buffer to string&lt;br /&gt;
    Dim strData As String&lt;br /&gt;
    strData = Space(m_ReceiveBufferLength)&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Copy data to string&lt;br /&gt;
    CopyMemory ByVal strData, m_ReceiveBuffer(0), m_ReceiveBufferLength&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset buffer&lt;br /&gt;
    m_ReceiveBufferLength = 0&lt;br /&gt;
    &lt;br /&gt;
    GetString = strData&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    GetString = &amp;quot;&amp;quot;&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Save received data to a file&lt;br /&gt;
Public Function SaveToFile(ByVal filePath As String) As Boolean&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if there&amp;#039;s data in the buffer&lt;br /&gt;
    If m_ReceiveBufferLength = 0 Then&lt;br /&gt;
        SaveToFile = False&lt;br /&gt;
        Exit Function&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Open the file&lt;br /&gt;
    Dim fileNum As Integer&lt;br /&gt;
    fileNum = FreeFile&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Write buffer to file&lt;br /&gt;
    Open filePath For Binary Access Write As #fileNum&lt;br /&gt;
    Put #fileNum, , m_ReceiveBuffer&lt;br /&gt;
    Close #fileNum&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset buffer&lt;br /&gt;
    m_ReceiveBufferLength = 0&lt;br /&gt;
    &lt;br /&gt;
    SaveToFile = True&lt;br /&gt;
    Exit Function&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    &amp;#039; Close file if open&lt;br /&gt;
    If fileNum &amp;gt; 0 Then&lt;br /&gt;
        Close #fileNum&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
    SaveToFile = False&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Winsock event handlers&lt;br /&gt;
Private Sub m_Winsock_Connect()&lt;br /&gt;
    &amp;#039; Connection established&lt;br /&gt;
    m_Connected = True&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset retry counter&lt;br /&gt;
    m_CurrentRetry = 0&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Stop connection timeout timer&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Start heartbeat timer&lt;br /&gt;
    m_HeartbeatTimer.Enabled = True&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Raise connected event&lt;br /&gt;
    RaiseEvent Connected&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_Winsock_Close()&lt;br /&gt;
    &amp;#039; Connection closed&lt;br /&gt;
    m_Connected = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Stop timers&lt;br /&gt;
    m_HeartbeatTimer.Enabled = False&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Reset transfer state&lt;br /&gt;
    m_TransferInProgress = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Raise disconnected event&lt;br /&gt;
    RaiseEvent Disconnected&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Auto reconnect if enabled&lt;br /&gt;
    If m_AutoReconnect Then&lt;br /&gt;
        AttemptConnection&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_Winsock_DataArrival(ByVal bytesTotal As Long)&lt;br /&gt;
    On Error GoTo ErrorHandler&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Resize buffer if needed&lt;br /&gt;
    If m_ReceiveBufferLength + bytesTotal &amp;gt; UBound(m_ReceiveBuffer) + 1 Then&lt;br /&gt;
        &amp;#039; Buffer overflow, resize&lt;br /&gt;
        ReDim Preserve m_ReceiveBuffer(0 To m_ReceiveBufferLength + bytesTotal - 1)&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Get data from winsock&lt;br /&gt;
    Dim tempBuffer() As Byte&lt;br /&gt;
    ReDim tempBuffer(0 To bytesTotal - 1)&lt;br /&gt;
    &lt;br /&gt;
    m_Winsock.GetData tempBuffer&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Process the packet&lt;br /&gt;
    &amp;#039; Check for header&lt;br /&gt;
    If bytesTotal &amp;gt;= 12 Then&lt;br /&gt;
        &amp;#039; Extract header information&lt;br /&gt;
        Dim transferID As Long, sequence As Integer, length As Integer, crc As Long&lt;br /&gt;
        &lt;br /&gt;
        CopyMemory transferID, tempBuffer(0), 4&lt;br /&gt;
        CopyMemory sequence, tempBuffer(4), 2&lt;br /&gt;
        CopyMemory length, tempBuffer(6), 2&lt;br /&gt;
        CopyMemory crc, tempBuffer(8), 4&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Verify this is a data packet with a valid header&lt;br /&gt;
        If bytesTotal &amp;gt;= 12 + length Then&lt;br /&gt;
            &amp;#039; Calculate CRC of the data&lt;br /&gt;
            Dim dataCRC As Long&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Create temp buffer for CRC calculation&lt;br /&gt;
            Dim crcBuffer() As Byte&lt;br /&gt;
            ReDim crcBuffer(0 To length - 1)&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Copy data portion&lt;br /&gt;
            CopyMemory crcBuffer(0), tempBuffer(12), length&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Calculate CRC&lt;br /&gt;
            dataCRC = CalculateCRC32(crcBuffer, length)&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Verify CRC&lt;br /&gt;
            If dataCRC = crc Then&lt;br /&gt;
                &amp;#039; Valid packet, copy to receive buffer&lt;br /&gt;
                CopyMemory m_ReceiveBuffer(m_ReceiveBufferLength), crcBuffer(0), length&lt;br /&gt;
                m_ReceiveBufferLength = m_ReceiveBufferLength + length&lt;br /&gt;
                &lt;br /&gt;
                &amp;#039; Update total received&lt;br /&gt;
                m_TotalBytesReceived = m_TotalBytesReceived + length&lt;br /&gt;
                &lt;br /&gt;
                &amp;#039; Raise data arrival event&lt;br /&gt;
                RaiseEvent DataArrival(length)&lt;br /&gt;
            Else&lt;br /&gt;
                &amp;#039; CRC mismatch, data corruption&lt;br /&gt;
                m_LastError = ERR_DATA_INTEGRITY&lt;br /&gt;
                m_LastErrorMessage = &amp;quot;Data integrity check failed&amp;quot;&lt;br /&gt;
                RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
            End If&lt;br /&gt;
        Else&lt;br /&gt;
            &amp;#039; Not a valid packet, just append to buffer&lt;br /&gt;
            CopyMemory m_ReceiveBuffer(m_ReceiveBufferLength), tempBuffer(0), bytesTotal&lt;br /&gt;
            m_ReceiveBufferLength = m_ReceiveBufferLength + bytesTotal&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Update total received&lt;br /&gt;
            m_TotalBytesReceived = m_TotalBytesReceived + bytesTotal&lt;br /&gt;
            &lt;br /&gt;
            &amp;#039; Raise data arrival event&lt;br /&gt;
            RaiseEvent DataArrival(bytesTotal)&lt;br /&gt;
        End If&lt;br /&gt;
    Else&lt;br /&gt;
        &amp;#039; Not enough data for header, just append to buffer&lt;br /&gt;
        CopyMemory m_ReceiveBuffer(m_ReceiveBufferLength), tempBuffer(0), bytesTotal&lt;br /&gt;
        m_ReceiveBufferLength = m_ReceiveBufferLength + bytesTotal&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Update total received&lt;br /&gt;
        m_TotalBytesReceived = m_TotalBytesReceived + bytesTotal&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Raise data arrival event&lt;br /&gt;
        RaiseEvent DataArrival(bytesTotal)&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    Exit Sub&lt;br /&gt;
    &lt;br /&gt;
ErrorHandler:&lt;br /&gt;
    m_LastError = Err.Number&lt;br /&gt;
    m_LastErrorMessage = Err.Description&lt;br /&gt;
    RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_Winsock_Error(ByVal Number As Integer, ByVal Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, ByVal CancelDisplay As Boolean)&lt;br /&gt;
    &amp;#039; Store error information&lt;br /&gt;
    m_LastError = Number&lt;br /&gt;
    m_LastErrorMessage = Description&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Handle connection reset errors with retry&lt;br /&gt;
    If Number = 10054 Then &amp;#039; Connection reset by peer&lt;br /&gt;
        m_Connected = False&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Stop timers&lt;br /&gt;
        m_HeartbeatTimer.Enabled = False&lt;br /&gt;
        m_ConnectionTimer.Enabled = False&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Reset transfer state&lt;br /&gt;
        m_TransferInProgress = False&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Auto reconnect if enabled&lt;br /&gt;
        If m_AutoReconnect Then&lt;br /&gt;
            AttemptConnection&lt;br /&gt;
        End If&lt;br /&gt;
    End If&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Raise error event&lt;br /&gt;
    RaiseEvent Error(Number, Description)&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_Winsock_ConnectionRequest(ByVal requestID As Long)&lt;br /&gt;
    &amp;#039; Forward connection request event&lt;br /&gt;
    RaiseEvent ConnectionRequest(requestID)&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_Winsock_SendComplete()&lt;br /&gt;
    &amp;#039; Forward send complete event&lt;br /&gt;
    RaiseEvent SendComplete&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if transfer is complete&lt;br /&gt;
    If m_TransferInProgress And m_TotalBytesSent &amp;gt; 0 Then&lt;br /&gt;
        m_TransferInProgress = False&lt;br /&gt;
        RaiseEvent TransferComplete(m_TransferID, True)&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Timer event handlers&lt;br /&gt;
Private Sub m_HeartbeatTimer_Timer()&lt;br /&gt;
    On Error Resume Next&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Send heartbeat packet to keep connection alive&lt;br /&gt;
    If m_Connected Then&lt;br /&gt;
        &amp;#039; Create a small heartbeat packet&lt;br /&gt;
        Dim heartbeat(0 To 3) As Byte&lt;br /&gt;
        heartbeat(0) = &amp;amp;HFF&lt;br /&gt;
        heartbeat(1) = &amp;amp;HFF&lt;br /&gt;
        heartbeat(2) = &amp;amp;HFF&lt;br /&gt;
        heartbeat(3) = &amp;amp;HFF&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Send heartbeat&lt;br /&gt;
        m_Winsock.SendData heartbeat&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
Private Sub m_ConnectionTimer_Timer()&lt;br /&gt;
    &amp;#039; Connection timeout&lt;br /&gt;
    m_ConnectionTimer.Enabled = False&lt;br /&gt;
    &lt;br /&gt;
    &amp;#039; Check if still not connected&lt;br /&gt;
    If Not m_Connected Then&lt;br /&gt;
        &amp;#039; Stop connection attempt&lt;br /&gt;
        On Error Resume Next&lt;br /&gt;
        m_Winsock.Close&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Set error&lt;br /&gt;
        m_LastError = ERR_CONNECTION_TIMEOUT&lt;br /&gt;
        m_LastErrorMessage = &amp;quot;Connection timeout&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Raise timeout event&lt;br /&gt;
        RaiseEvent Timeout&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Try to reconnect if auto reconnect is enabled&lt;br /&gt;
        If m_AutoReconnect And m_CurrentRetry &amp;lt; m_RetryCount Then&lt;br /&gt;
            AttemptConnection&lt;br /&gt;
        Else&lt;br /&gt;
            &amp;#039; Raise error event&lt;br /&gt;
            RaiseEvent Error(m_LastError, m_LastErrorMessage)&lt;br /&gt;
        End If&lt;br /&gt;
    End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Property procedures&lt;br /&gt;
Public Property Get BufferSize() As Long&lt;br /&gt;
    BufferSize = m_BufferSize&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let BufferSize(ByVal value As Long)&lt;br /&gt;
    &amp;#039; Ensure buffer size is within limits&lt;br /&gt;
    If value &amp;gt; 0 And value &amp;lt;= MAX_BUFFER_SIZE Then&lt;br /&gt;
        m_BufferSize = value&lt;br /&gt;
        &lt;br /&gt;
        &amp;#039; Resize buffers&lt;br /&gt;
        ReDim Preserve m_SendBuffer(0 To m_BufferSize - 1)&lt;br /&gt;
        ReDim Preserve m_ReceiveBuffer(0 To m_BufferSize - 1)&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get ChunkSize() As Long&lt;br /&gt;
    ChunkSize = m_ChunkSize&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let ChunkSize(ByVal value As Long)&lt;br /&gt;
    &amp;#039; Ensure chunk size is reasonable&lt;br /&gt;
    If value &amp;gt; 0 And value &amp;lt;= MAX_BUFFER_SIZE Then&lt;br /&gt;
        m_ChunkSize = value&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get Timeout() As Long&lt;br /&gt;
    Timeout = m_Timeout&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let Timeout(ByVal value As Long)&lt;br /&gt;
    If value &amp;gt; 0 Then&lt;br /&gt;
        m_Timeout = value&lt;br /&gt;
        m_ConnectionTimer.Interval = value&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get RetryCount() As Integer&lt;br /&gt;
    RetryCount = m_RetryCount&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let RetryCount(ByVal value As Integer)&lt;br /&gt;
    If value &amp;gt;= 0 Then&lt;br /&gt;
        m_RetryCount = value&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get AutoReconnect() As Boolean&lt;br /&gt;
    AutoReconnect = m_AutoReconnect&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let AutoReconnect(ByVal value As Boolean)&lt;br /&gt;
    m_AutoReconnect = value&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get HeartbeatInterval() As Long&lt;br /&gt;
    HeartbeatInterval = m_HeartbeatInterval&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let HeartbeatInterval(ByVal value As Long)&lt;br /&gt;
    If value &amp;gt; 0 Then&lt;br /&gt;
        m_HeartbeatInterval = value&lt;br /&gt;
        m_HeartbeatTimer.Interval = value&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get SessionID() As String&lt;br /&gt;
    SessionID = m_SessionID&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get RemoteHost() As String&lt;br /&gt;
    RemoteHost = m_RemoteHost&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get RemotePort() As Long&lt;br /&gt;
    RemotePort = m_RemotePort&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get LocalPort() As Long&lt;br /&gt;
    LocalPort = m_LocalPort&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Let LocalPort(ByVal value As Long)&lt;br /&gt;
    If value &amp;gt; 0 Then&lt;br /&gt;
        m_LocalPort = value&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get IsConnected() As Boolean&lt;br /&gt;
    IsConnected = m_Connected&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get LastError() As Long&lt;br /&gt;
    LastError = m_LastError&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get LastErrorMessage() As String&lt;br /&gt;
    LastErrorMessage = m_LastErrorMessage&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get BytesSent() As Long&lt;br /&gt;
    BytesSent = m_TotalBytesSent&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get BytesReceived() As Long&lt;br /&gt;
    BytesReceived = m_TotalBytesReceived&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
Public Property Get State() As Integer&lt;br /&gt;
    If Not m_Winsock Is Nothing Then&lt;br /&gt;
        State = m_Winsock.State&lt;br /&gt;
    Else&lt;br /&gt;
        State = SOCKET_CLOSED&lt;br /&gt;
    End If&lt;br /&gt;
End Property&lt;br /&gt;
&lt;br /&gt;
&amp;#039; Utility function to copy memory (needs a declare statement in a module)&lt;br /&gt;
&amp;#039; Private Declare Sub CopyMemory Lib &amp;quot;kernel32&amp;quot; Alias &amp;quot;RtlMoveMemory&amp;quot; (Destination As Any, Source As Any, ByVal Length As Long)&lt;br /&gt;
&amp;#039; Private Declare Sub Sleep Lib &amp;quot;kernel32&amp;quot; (ByVal dwMilliseconds As Long)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>XenoEngineer</name></author>
	</entry>
</feed>