Skip to content

cWinsock Class Development Documentation\r\n\r\n> ๐Ÿš€ cWinsock - Simplified VB6 Winsock wrapper library, developed by woeoio@qq.com based on VbAsyncSocket (author: wqweto@gmail.com)\r\n\r\n## ๐Ÿ“– Table of Contents\r\n\r\n- Overview\r\n- Core Highlights\r\n- Comparison with Native Winsock Control\r\n- Quick Start\r\n- Architecture Design\r\n- Documentation Index\r\n\r\n---\r\n\r\n## Overview\r\n\r\ncWinsock is a lightweight network communication class designed for VB6, providing an event-driven programming model similar to the classic Winsock control, but with a simpler API and more powerful features.\r\n\r\n### โœจ Main Features\r\n\r\n- ๐Ÿ”Œ Pure class implementation - No controls required, direct object programming\r\n- ๐ŸŽฏ Direct object reference - Event parameters directly pass client objects, no index lookup needed\r\n- ๐ŸŒ Dual protocol support - Simultaneously supports TCP and UDP communication\r\n- ๐Ÿข Automatic client management - Server mode automatically manages all connected clients\r\n- ๐Ÿ“ฆ Smart data encoding - Supports multiple text encodings (GBK/ACP, UTF-8, Unicode)\r\n- ๐Ÿ›ก๏ธ Connection interception - Blacklist/whitelist mechanism via ConnectionRequest event\r\n- ๐Ÿ”„ Event proxy mechanism - Server client data unified through server event triggering\r\n- ๐Ÿ’พ Flexible data types - Supports both string and byte array data formats\r\n- ๐Ÿ“ฆ Data packet protocol - Three built-in protocols solve TCP fragmentation/sticky packet, automatic packet/unpacket\r\n- ๐Ÿ’“ Smart heartbeat mechanism - Embedded timer auto-drive, server timeout detection, client smart keep-alive\r\n- ๐Ÿ”’ TLS/SSL support - Chain function configuration for TLS, both client and server can encrypt communication\r\n- ๐ŸŽฏ GetData enhanced - Return value style convenience methods, one-line code to get text/Hex/byte array\r\n\r\n---\r\n\r\n## Core Highlights\r\n\r\n### 1๏ธโƒฃ Direct Object Reference Event Model ๐Ÿ”—\r\n\r\nTraditional Winsock control problems:\r\nvb\r\n' Need to manage clients via index\r\nPrivate Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)\r\n Dim i As Integer\r\n ' Find available index or dynamically load control...\r\nEnd Sub\r\n\r\n' When processing data, need to know which client\r\nPrivate Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)\r\n Winsock1(Index).GetData strData\r\nEnd Sub\r\n\r\n\r\ncWinsock's elegant solution:\r\nvb\r\n' Event directly passes client object!\r\nPrivate Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)\r\n ' Directly operate on Client object, no index needed\r\n Debug.Print "New client: " & Client.RemoteHostIP\r\n \r\n ' Reject blacklist IP\r\n If IsBlacklisted(Client.RemoteHostIP) Then\r\n DisConnect = True\r\n End If\r\nEnd Sub\r\n\r\n' Data event also directly passes client object\r\nPrivate Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n ' Directly read data from Client object, no index lookup needed\r\nEnd Sub\r\n\r\n\r\n---\r\n\r\n### 2๏ธโƒฃ Smart TCP Client Event Proxy ๐Ÿ“ก\r\n\r\nProblem scenario: After server accepts new connection and creates client object, its data reception event cannot be subscribed by host.\r\n\r\ncWinsock's solution: Automatically trigger events through parent server object\r\n\r\nvb\r\n' In server object's DataArrival event\r\n' Can receive data from all clients!\r\nPrivate Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n \r\n ' Client parameter is the specific client object\r\n ' Can directly reply to that client\r\n Client.SendData "Echo: " & sData\r\nEnd Sub\r\n\r\n\r\nHow it works:\r\n1. Server accepts new connection, creates independent client socket object\r\n2. Client receives data, triggers event via parent server's RaiseDataArrivalEvent method\r\n3. Host only needs to subscribe to server object events to handle all client data\r\n\r\n---\r\n\r\n### 3๏ธโƒฃ UDP Server Virtual Client Management ๐ŸŽญ\r\n\r\nUDP is a connectionless protocol, but cWinsock creates virtual client objects for each different remote address:port combination, simulating connection behavior:\r\n\r\nvb\r\n' UDP server mode\r\nPrivate Sub m_oUdp_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)\r\n ' Each remote address:port combination that communicates for the first time\r\n ' Automatically creates a virtual Client object\r\n Debug.Print "UDP client: " & Client.RemoteHostIP & ":" & Client.RemotePort\r\nEnd Sub\r\n\r\nPrivate Sub m_oUdp_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n \r\n ' Can reply to specific virtual client\r\n ' cWinsock automatically uses correct target address:port\r\n Client.SendData "Reply: " & sData\r\nEnd Sub\r\n\r\n\r\n---\r\n\r\n### 4๏ธโƒฃ Connection Request Interception Mechanism ๐Ÿšฆ\r\n\r\nImplement connection interception via DisConnect parameter in ConnectionRequest event:\r\n\r\nvb\r\nPrivate Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)\r\n ' Blacklist check\r\n If IsInBlacklist(Client.RemoteHostIP) Then\r\n Debug.Print "Reject blacklist IP: " & Client.RemoteHostIP\r\n DisConnect = True ' Set to True, automatically disconnect and cleanup resources\r\n Exit Sub\r\n End If\r\n \r\n ' Port range restriction\r\n If Client.RemotePort < 1024 Then\r\n Debug.Print "Reject privileged port connection: " & Client.RemotePort\r\n DisConnect = True\r\n Exit Sub\r\n End If\r\n \r\n ' Whitelist mode\r\n If m_bWhitelistMode And Not IsInWhitelist(Client.RemoteHostIP) Then\r\n Debug.Print "Not in whitelist, reject connection"\r\n DisConnect = True\r\n Exit Sub\r\n End If\r\n \r\n ' Keep DisConnect False, accept connection\r\n Debug.Print "Accept connection: " & Client.RemoteHostIP & ":" & Client.RemotePort\r\nEnd Sub\r\n\r\n\r\n---\r\n\r\n### 5๏ธโƒฃ Flexible Text Encoding Support ๐Ÿ”ค\r\n\r\nSupports multiple encoding methods to adapt to different scenarios:\r\n\r\nvb\r\n' Default uses ACP/GBK encoding (compatible with VB6)\r\nClient.SendData "ไธญๆ–‡ๆต‹่ฏ•"\r\nClient.GetData sData ' Default ACP\r\n\r\n' Use UTF-8 encoding (recommended for network transmission)\r\nClient.SendData "ไธญๆ–‡ๆต‹่ฏ•", ucsScpUtf8\r\nClient.GetData sData, , , ucsScpUtf8\r\n\r\n' Use Unicode (no conversion, keep wide characters)\r\nClient.SendData "ไธญๆ–‡ๆต‹่ฏ•", ScpUnicode\r\nClient.GetData sData, , , ScpUnicode\r\n\r\n' Send byte array (no encoding involved)\r\nDim baData() As Byte\r\nbaData = GetByteArray()\r\nClient.SendData baData\r\n\r\n\r\nEncoding enumeration:\r\n- ScpAcp (0) - System default code page (GBK on Chinese Windows)\r\n- ScpUtf8 (65001) - UTF-8 encoding\r\n- ScpUnicode (-1) - Unicode, no encoding conversion\r\n\r\n---\r\n\r\n### 6๏ธโƒฃ Automatic Client Collection Management ๐Ÿ“š\r\n\r\nIn server mode, automatically maintains all connected clients:\r\n\r\nvb\r\n' Client collection automatically initialized when server starts\r\nm_oServer.Listen 8080\r\n\r\n' Iterate through all clients\r\nDim oClient As cWinsock\r\nFor Each oClient In m_oServer.Clients\r\n Debug.Print "Client: " & oClient.ClientId & " - " & oClient.RemoteHostIP\r\nNext\r\n\r\n' Get client count\r\nDebug.Print "Current connections: " & m_oServer.ClientCount\r\n\r\n' Manually remove client (usually automatically handled by CloseEvent)\r\nm_oServer.RemoveClient oClient\r\n\r\n\r\n---\r\n\r\n### 7๏ธโƒฃ Smart Remote Address Resolution ๐ŸŒ\r\n\r\nUDP server mode supports domain name resolution:\r\n\r\nvb\r\n' Set remote address (can be IP or domain name)\r\nm_oUdp.RemoteHost = "example.com"\r\nm_oUdp.RemotePort = 8888\r\n\r\n' Domain name automatically resolved when sending\r\nm_oUdp.SendData "Hello"\r\n\r\n\r\nInternal logic:\r\nvb\r\n' Smart selection in SendData method\r\nIf LenB(m_sRemoteHostIP) <> 0 Then\r\n ' If resolved IP exists, prioritize using it\r\n m_oSocket.SendText Data, m_sRemoteHostIP, m_lRemotePort, CodePage\r\nElseIf LenB(m_sRemoteHost) <> 0 Then\r\n ' Otherwise use hostname, underlying layer automatically resolves domain name\r\n m_oSocket.SendText Data, m_sRemoteHost, m_lRemotePort, CodePage\r\nEnd If\r\n\r\n\r\n---\r\n\r\n### 8๏ธโƒฃ Data Buffer Management ๐Ÿ“Š\r\n\r\nBuilt-in data buffer, supports partial reading:\r\n\r\nvb\r\n' When receiving data, only read first 100 bytes\r\nDim sPartial As String\r\nClient.GetData sPartial, vbString, 100\r\n\r\n' Remaining data automatically saved in internal buffer\r\n' Will continue to return remaining data on next read\r\n\r\n\r\nInternal buffer mechanism:\r\n- TCP and client mode: Use m_baRecvBuffer private member\r\n- UDP server virtual client: Use UserData property for temporary storage\r\n\r\n---\r\n\r\n### 9๏ธโƒฃ Data Packet Protocol ๐Ÿ“ฆ\r\n\r\nProblem scenario: TCP is a streaming protocol with data fragmentation and sticky packet issues\r\n\r\nvb\r\n' Sender sends continuously\r\nClient.SendData "Hello"\r\nClient.SendData "World"\r\n\r\n' Receiver may receive\r\n"HelloWorld" ' Sticky packet\r\n"Hel" ' Fragmentation\r\n"loWorld"\r\n\r\n\r\ncWinsock built-in three protocols to solve this:\r\n- Character delimiter protocol (ppDelimiter) - Supports custom delimiters (e.g., \r\n, |, \0, etc.)\r\n- Fixed length protocol (ppFixedLength) - Suitable for fixed-length messages\r\n- Length header protocol (ppLengthHeader) - Supports 2/4 byte headers, configurable endianness\r\n\r\nUsage example:\r\nvb\r\n' Set character delimiter protocol\r\nServer.PacketProtocol = ppDelimiter\r\nServer.Delimiter = vbCrLf\r\n\r\n' Or set length header protocol\r\nServer.PacketProtocol = ppLengthHeader\r\nServer.HeaderBytes = 4 ' 4-byte length header\r\nServer.HeaderEndian = eeLittleEndian\r\n\r\n' Send automatic packet\r\nClient.SendData "Hello World" ' Automatically append protocol marker\r\n\r\n' Receive automatic unpacket - use MessageArrival event\r\nPrivate Sub Server_MessageArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetDataText sData ' Get complete message\r\nEnd Sub\r\n\r\n\r\nKey features:\r\n- Each client has independent protocol instance, buffers isolated from each other\r\n- New clients automatically inherit server protocol configuration\r\n- In protocol mode, only MessageArrival is triggered, not DataArrival, to avoid duplicate reads\r\n- Heartbeat data goes through protocol encoding, does not pollute protocol state machine\r\n- MaxPacketSize/MaxBufferSize safety limits, prevent malicious packets and memory exhaustion\r\n- UDP clients also support packet protocol\r\n\r\nDetailed description: See Packet Protocol and Heartbeat Mechanism, Properties Reference, Events Reference\r\n\r\n---\r\n\r\n### ๐Ÿ”Ÿ TCP Smart Heartbeat ๐Ÿ’“\r\n\r\nProblem scenario: TCP connection may silently disconnect due to network issues, need keep-alive mechanism\r\n\r\ncWinsock built-in heartbeat manager, embedded cTimer auto-drive, no external timer needed:\r\n\r\nvb\r\n' Server: Timeout detection (default 120 seconds)\r\nServer.HeartbeatTimeout = 120\r\nServer.AutoHeartbeat = True\r\n\r\n' Client: Heartbeat keep-alive (default 50 seconds interval)\r\nClient.HeartbeatInterval = 50\r\nClient.AutoHeartbeat = True\r\n\r\n' Events\r\nPrivate Sub Server_ClientTimeout(Client As cWinsock)\r\n Debug.Print "Client timeout: " & Client.RemoteHostIP\r\n ' Already auto-disconnected, can do cleanup\r\nEnd Sub\r\n\r\nPrivate Sub Client_HeartbeatSent(Client As cWinsock)\r\n Debug.Print "Heartbeat sent"\r\nEnd Sub\r\n\r\n\r\nKey features:\r\n- Embedded cTimer (10-second interval), AutoHeartbeat = True for full auto operation\r\n- Server: Polls client idle time, auto-disconnects zombie connections on timeout\r\n- Client: Smart skip - skips heartbeat when data send/receive exists, saves bandwidth\r\n- Each send/receive auto-updates LastActivityTime\r\n- New clients automatically inherit server heartbeat configuration\r\n- Heartbeat data goes through protocol encoding, does not pollute packet protocol state machine\r\n\r\nDetailed description: See Packet Protocol and Heartbeat Mechanism, Properties Reference, Events Reference\r\n\r\n---\r\n\r\n### 1๏ธโƒฃ1๏ธโƒฃ GetData Enhanced Methods ๐ŸŽฏ\r\n\r\nProblem scenario: Getting data requires manual format conversion, code is tedious\r\n\r\ncWinsock provides return value style convenience methods, one-line code ready to use:\r\n\r\nvb\r\n' Directly return text\r\nDebug.Print Client.GetDataText() ' ACP/GBK\r\nDebug.Print Client.GetDataTextUTF8() ' UTF-8\r\nDebug.Print Client.GetDataTextUnicode() ' Unicode\r\n\r\n' Directly return hexadecimal\r\nDebug.Print Client.GetDataHex() ' "48 65 6C 6C 6F"\r\n\r\n' Directly return byte array\r\nDim baData() As Byte\r\nbaData = Client.GetDataByteArray()\r\n\r\n' Condition check\r\nIf Client.GetDataText() = "Hello" Then\r\n Debug.Print "Received Hello"\r\nEnd If\r\n\r\n' Compatible with old method\r\nDim sData As String\r\nsData = Client.GetDataToString() ' Equivalent to GetDataText()\r\n\r\n\r\nDetailed description: See Methods Reference\r\n\r\n---\r\n\r\n## Comparison with Native Winsock Control\r\n\r\n| Feature | Native Winsock Control | cWinsock Class |\r\n|---------|------------------------|-----------------|\r\n| Object model | Control array, managed via index | Pure class object, direct reference |\r\n| Event parameters | Pass index, need reverse lookup object | Directly pass client object |\r\n| Client management | Manually maintain index and controls | Automatically manage Clients collection |\r\n| UDP server | Connectionless, no client concept | Virtual client objects |\r\n| Connection interception | Need to manually close after Accept | Event parameter control, auto cleanup |\r\n| Encoding support | Fixed encoding | Multiple encoding options |\r\n| Data types | String/byte array | String/byte array + flexible conversion + return value convenience methods |\r\n| Event unification | Independent event per client | Server triggers all client events uniformly |\r\n| Packet protocol | Need manual sticky packet handling | Three built-in protocols, automatic packet/unpacket |\r\n| Heartbeat keep-alive | Need manual implementation | Built-in heartbeat manager, full auto drive |\r\n| Resource management | Need to manually Unload controls | Auto cleanup and garbage collection |\r\n\r\n---\r\n\r\n## Quick Start\r\n\r\n### TCP Client Example\r\n\r\nvb\r\nPrivate WithEvents m_oClient As cWinsock\r\n\r\nPrivate Sub Form_Load()\r\n Set m_oClient = New cWinsock\r\n m_oClient.Protocol = sckTCPProtocol\r\n m_oClient.Connect "127.0.0.1", 8080\r\nEnd Sub\r\n\r\nPrivate Sub m_oClient_Connect(Client As cWinsock)\r\n Debug.Print "Connected to server"\r\n Client.SendData "Hello, Server!"\r\nEnd Sub\r\n\r\nPrivate Sub m_oClient_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n Debug.Print "Received data: " & sData\r\nEnd Sub\r\n\r\nPrivate Sub Form_Unload(Cancel As Integer)\r\n m_oClient.Close_\r\nEnd Sub\r\n\r\n\r\n### TCP Server Example\r\n\r\nvb\r\nPrivate WithEvents m_oServer As cWinsock\r\n\r\nPrivate Sub Form_Load()\r\n Set m_oServer = New cWinsock\r\n m_oServer.Protocol = sckTCPProtocol\r\n m_oServer.Listen 8080\r\nEnd Sub\r\n\r\nPrivate Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)\r\n Debug.Print "New client connection: " & Client.RemoteHostIP\r\n ' DisConnect = False means accept connection\r\nEnd Sub\r\n\r\nPrivate Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n Debug.Print "Data from client " & Client.ClientId & ": " & sData\r\n \r\n ' Echo\r\n Client.SendData "Echo: " & sData\r\nEnd Sub\r\n\r\nPrivate Sub m_oServer_CloseEvent(Client As cWinsock)\r\n Debug.Print "Client disconnected: " & Client.ClientId\r\nEnd Sub\r\n\r\nPrivate Sub Form_Unload(Cancel As Integer)\r\n m_oServer.Close_\r\nEnd Sub\r\n\r\n\r\n### UDP Communication Example\r\n\r\nvb\r\nPrivate WithEvents m_oUdp As cWinsock\r\n\r\nPrivate Sub Form_Load()\r\n Set m_oUdp = New cWinsock\r\n m_oUdp.Protocol = sckUDPProtocol\r\n m_oUdp.Bind 8888\r\nEnd Sub\r\n\r\nPrivate Sub cmdSend_Click()\r\n m_oUdp.RemoteHost = "127.0.0.1"\r\n m_oUdp.RemotePort = 9999\r\n m_oUdp.SendData "Hello, UDP!"\r\nEnd Sub\r\n\r\nPrivate Sub m_oUdp_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)\r\n Dim sData As String\r\n Client.GetData sData\r\n Debug.Print "Received UDP data (" & Client.RemoteHostIP & ":" & Client.RemotePort & "): " & sData\r\nEnd Sub\r\n\r\n\r\n---\r\n\r\n## Architecture Design\r\n\r\n### Class Hierarchy\r\n\r\n\r\ncWinsock (public class)\r\n โ”œโ”€โ”€ m_oSocket: cTlsSocket (internal encapsulation, supports TLS)\r\n โ”œโ”€โ”€ m_cClients: Collection (client collection)\r\n โ”œโ”€โ”€ m_oParentServer: cWinsock (parent server reference, clients only)\r\n โ”œโ”€โ”€ m_oPacketProtocol: cPacketProtocol (packet protocol handler)\r\n โ”œโ”€โ”€ m_oHeartbeat: cHeartbeat (heartbeat manager, embedded cTimer)\r\n โ””โ”€โ”€ Events: Connect, CloseEvent, ConnectionRequest, DataArrival, MessageArrival,\r\n SendProgress, SendComplete, Error, ClientTimeout, HeartbeatSent, ServerCertificateVerify\r\n\r\n\r\n### Sub-module Classes\r\n\r\n| Class | File | Responsibility |\r\n|-------|------|---------------|\r\n| cPacketProtocol | cPacketProtocol.cls | Data packet protocol: delimiter/fixed-length/length-header, solves TCP fragmentation/sticky packet |\r\n| cHeartbeat | cHeartbeat.cls | Heartbeat management: embedded cTimer auto-drive, timeout detection, heartbeat keep-alive |\r\n\r\n### Object Relationship Diagram\r\n\r\n\r\nServer object\r\nโ”œโ”€โ”€ Socket (listening socket)\r\nโ”œโ”€โ”€ Clients collection\r\nโ”‚ โ”œโ”€โ”€ Client object 1 (cWinsock)\r\nโ”‚ โ”‚ โ”œโ”€โ”€ Socket (independent connection)\r\nโ”‚ โ”‚ โ””โ”€โ”€ ParentServer โ†’ Server object\r\nโ”‚ โ”œโ”€โ”€ Client object 2 (cWinsock)\r\nโ”‚ โ”‚ โ”œโ”€โ”€ Socket (independent connection)\r\nโ”‚ โ”‚ โ””โ”€โ”€ ParentServer โ†’ Server object\r\nโ”‚ โ””โ”€โ”€ ...\r\nโ””โ”€โ”€ Event handler\r\n โ””โ”€โ”€ All client data triggered through this\r\n\r\n\r\n### State Machine\r\n\r\n\r\nsckClosed (0)\r\n โ”œโ”€ Connect() โ†’ sckResolvingHost โ†’ sckHostResolved โ†’ sckConnecting โ†’ sckConnected (7)\r\n โ”œโ”€ Listen() โ†’ sckListening (2)\r\n โ””โ”€ Bind() โ†’ sckOpen (1)\r\n\r\nsckListening (2)\r\n โ””โ”€ OnAccept โ†’ Create client โ†’ sckConnected\r\n\r\nsckConnected (7)\r\n โ””โ”€ OnClose โ†’ sckClosed\r\n\r\nError โ†’ sckError (9)\r\n\r\n\r\n---\r\n\r\n## Documentation Index\r\n\r\n| Document | Description |\r\n|----------|-------------|\r\n| Packet Protocol and Heartbeat | Detailed description and complete examples for packet protocol and heartbeat mechanism |\r\n| Events Reference | Detailed explanation and usage examples for all events |\r\n| Properties Reference | Description, type, and purpose of all properties |\r\n| Methods Reference | Parameters, return values, and usage examples for all methods |\r\n| Encoding Guide | Usage instructions and best practices for text encoding |\r\n| TCP Programming | TCP client and server programming guide |\r\n| UDP Programming | UDP communication programming guide |\r\n| Best Practices | Solutions for common scenarios and performance optimization recommendations |\r\n| TLS/SSL Support | Configuration and usage instructions for TLS encrypted communication |\r\n| Certificate Mode Details | Detailed introduction of three certificate sources (file/Windows store/memory) |\r\n| Development Plan | Project development progress tracking and future feature planning |\r\n\r\n---\r\n\r\n## License\r\n\r\nBased on VbAsyncSocket (wqweto@gmail.com)\r\n\r\n---\r\n\r\n## Author\r\n\r\ncWinsock: woeoio@qq.com \r\nVbAsyncSocket: wqweto@gmail.com\r\n\r\n---\r\n\r\nLast Updated: 2026-06-09\r\n โ€‹

VB6 and LOGO copyright of Microsoft Corporation