Skip to content

cWinsock Class Development Documentation

🚀 cWinsock - Simplified VB6 Winsock wrapper library, developed by woeoio@qq.com based on VbAsyncSocket (author: wqweto@gmail.com)

📖 Table of Contents


Overview

cWinsock 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.

✨ Main Features

  • 🔌 Pure class implementation - No controls required, direct object programming
  • 🎯 Direct object reference - Event parameters directly pass client objects, no index lookup needed
  • 🌐 Dual protocol support - Simultaneously supports TCP and UDP communication
  • 🏢 Automatic client management - Server mode automatically manages all connected clients
  • 📦 Smart data encoding - Supports multiple text encodings (GBK/ACP, UTF-8, Unicode)
  • 🛡️ Connection interception - Blacklist/whitelist mechanism via ConnectionRequest event
  • 🔄 Event proxy mechanism - Server client data unified through server event triggering
  • 💾 Flexible data types - Supports both string and byte array data formats
  • 🚀 Planned features - Data packet protocol, TCP smart heartbeat, GetData enhanced methods

Core Highlights

1️⃣ Direct Object Reference Event Model 🔗

Traditional Winsock control problems:

vb
' Need to manage clients via index
Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    Dim i As Integer
    ' Find available index or dynamically load control...
End Sub

' When processing data, need to know which client
Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Winsock1(Index).GetData strData
End Sub

cWinsock's elegant solution:

vb
' Event directly passes client object!
Private Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)
    ' Directly operate on Client object, no index needed
    Debug.Print "New client: " & Client.RemoteHostIP
    
    ' Reject blacklist IP
    If IsBlacklisted(Client.RemoteHostIP) Then
        DisConnect = True
    End If
End Sub

' Data event also directly passes client object
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    ' Directly read data from Client object, no index lookup needed
End Sub

2️⃣ Smart TCP Client Event Proxy 📡

Problem scenario: After server accepts new connection and creates client object, its data reception event cannot be subscribed by host.

cWinsock's solution: Automatically trigger events through parent server object

vb
' In server object's DataArrival event
' Can receive data from all clients!
Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    ' Client parameter is the specific client object
    ' Can directly reply to that client
    Client.SendData "Echo: " & sData
End Sub

How it works:

  1. Server accepts new connection, creates independent client socket object
  2. Client receives data, triggers event via parent server's RaiseDataArrivalEvent method
  3. Host only needs to subscribe to server object events to handle all client data

3️⃣ UDP Server Virtual Client Management 🎭

UDP is a connectionless protocol, but cWinsock creates virtual client objects for each different remote address:port combination, simulating connection behavior:

vb
' UDP server mode
Private Sub m_oUdp_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)
    ' Each remote address:port combination that communicates for the first time
    ' Automatically creates a virtual Client object
    Debug.Print "UDP client: " & Client.RemoteHostIP & ":" & Client.RemotePort
End Sub

Private Sub m_oUdp_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    
    ' Can reply to specific virtual client
    ' cWinsock automatically uses correct target address:port
    Client.SendData "Reply: " & sData
End Sub

4️⃣ Connection Request Interception Mechanism 🚦

Implement connection interception via DisConnect parameter in ConnectionRequest event:

vb
Private Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)
    ' Blacklist check
    If IsInBlacklist(Client.RemoteHostIP) Then
        Debug.Print "Reject blacklist IP: " & Client.RemoteHostIP
        DisConnect = True  ' Set to True, automatically disconnect and cleanup resources
        Exit Sub
    End If
    
    ' Port range restriction
    If Client.RemotePort < 1024 Then
        Debug.Print "Reject privileged port connection: " & Client.RemotePort
        DisConnect = True
        Exit Sub
    End If
    
    ' Whitelist mode
    If m_bWhitelistMode And Not IsInWhitelist(Client.RemoteHostIP) Then
        Debug.Print "Not in whitelist, reject connection"
        DisConnect = True
        Exit Sub
    End If
    
    ' Keep DisConnect False, accept connection
    Debug.Print "Accept connection: " & Client.RemoteHostIP & ":" & Client.RemotePort
End Sub

5️⃣ Flexible Text Encoding Support 🔤

Supports multiple encoding methods to adapt to different scenarios:

vb
' Default uses ACP/GBK encoding (compatible with VB6)
Client.SendData "中文测试"
Client.GetData sData  ' Default ACP

' Use UTF-8 encoding (recommended for network transmission)
Client.SendData "中文测试", ucsScpUtf8
Client.GetData sData, , , ucsScpUtf8

' Use Unicode (no conversion, keep wide characters)
Client.SendData "中文测试", ScpUnicode
Client.GetData sData, , , ScpUnicode

' Send byte array (no encoding involved)
Dim baData() As Byte
baData = GetByteArray()
Client.SendData baData

Encoding enumeration:

  • ScpAcp (0) - System default code page (GBK on Chinese Windows)
  • ScpUtf8 (65001) - UTF-8 encoding
  • ScpUnicode (-1) - Unicode, no encoding conversion

6️⃣ Automatic Client Collection Management 📚

In server mode, automatically maintains all connected clients:

vb
' Client collection automatically initialized when server starts
m_oServer.Listen 8080

' Iterate through all clients
Dim oClient As cWinsock
For Each oClient In m_oServer.Clients
    Debug.Print "Client: " & oClient.Tag & " - " & oClient.RemoteHostIP
Next

' Get client count
Debug.Print "Current connections: " & m_oServer.ClientCount

' Manually remove client (usually automatically handled by CloseEvent)
m_oServer.RemoveClient oClient

7️⃣ Smart Remote Address Resolution 🌐

UDP server mode supports domain name resolution:

vb
' Set remote address (can be IP or domain name)
m_oUdp.RemoteHost = "example.com"
m_oUdp.RemotePort = 8888

' Domain name automatically resolved when sending
m_oUdp.SendData "Hello"

Internal logic:

vb
' Smart selection in SendData method
If LenB(m_sRemoteHostIP) <> 0 Then
    ' If resolved IP exists, prioritize using it
    m_oSocket.SendText Data, m_sRemoteHostIP, m_lRemotePort, CodePage
ElseIf LenB(m_sRemoteHost) <> 0 Then
    ' Otherwise use hostname, underlying layer automatically resolves domain name
    m_oSocket.SendText Data, m_sRemoteHost, m_lRemotePort, CodePage
End If

8️⃣ Data Buffer Management 📊

Built-in data buffer, supports partial reading:

vb
' When receiving data, only read first 100 bytes
Dim sPartial As String
Client.GetData sPartial, vbString, 100

' Remaining data automatically saved in internal buffer
' Will continue to return remaining data on next read

Internal buffer mechanism:

  • TCP and client mode: Use m_baRecvBuffer private member
  • UDP server virtual client: Use UserData property for temporary storage

9️⃣ Planned Feature Highlights (In Development) 🚀

Data Packet Protocol 📦

Problem scenario: TCP is a streaming protocol with data fragmentation and sticky packet issues

vb
' Sender sends continuously
Client.SendData "Hello"
Client.SendData "World"

' Receiver may receive
"HelloWorld"  ' Sticky packet
"Hel"         ' Fragmentation
"loWorld"

Planned implementation:

  • Character delimiter protocol
    • Default delimiter: \0 (VbNullChar)
    • Support custom arbitrary delimiters (such as \r\n, |, etc.)
    • Applicable to text protocols
  • Fixed length protocol - Applicable to fixed-length messages
  • Length header protocol - Applicable to binary protocols
  • Custom protocol - Support user callback functions
  • Unified protocol interface - All protocol classes provide unified Encode (packet) and Decode (unpacket) functions, internally automatically cache fragmented data
  • Independent protocol instance per client - In multi-client scenarios, each client holds independent protocol instance, buffers isolated from each other
  • Automatic processing - Automatically packet/unpacket after setting

Expected API:

vb
' Set character delimiter protocol (use default \r\n)
Server.PacketProtocol = ppDelimiter

' Customize delimiter as null character
Server.Delimiter = vbNullChar

' Send automatic packet
Client.SendData "Hello World"  ' Automatically append delimiter

' Receive automatic unpacket (handled by protocol class's internal Decode function)
Private Sub Server_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData  ' Automatically assemble complete message
End Sub

Detailed design: See Development Plan


TCP Smart Heartbeat 💓

Problem scenario: TCP connection may silently disconnect due to network issues, need keep-alive mechanism

Server features:

  • Periodically poll client last communication time
  • Automatically disconnect after 2 minutes of no communication
  • Trigger ClientTimeout event
  • Prevent zombie connections from occupying resources
  • Important: Immediately reset client's LastActivityTime after each send/receive to ensure heartbeat skipping cycle won't be misjudged as timeout

Client features:

  • Automatically send heartbeat packet (1 byte) every 50 seconds
  • Smart skip: Skip current cycle if recent data send/receive exists
  • Keep connection active, prevent timeout disconnect

Expected API:

vb
' Server configuration
Server.HeartbeatTimeout = 120  ' 2 minutes timeout
Server.AutoHeartbeat = True    ' Auto enable

' Client configuration
Client.HeartbeatInterval = 50   ' 50 seconds interval
Client.HeartbeatData = &H0     ' Heartbeat packet content
Client.AutoHeartbeat = True

' Events
Private Sub Server_ClientTimeout(Client As cWinsock)
    Debug.Print "Client timeout: " & Client.RemoteHostIP
End Sub

Private Sub Client_HeartbeatSent()
    Debug.Print "Heartbeat sent"
End Sub

Detailed design: See Development Plan


GetData Enhanced Methods 🎯

Problem scenario: Getting data requires manual format conversion, code is tedious

Design principles:

  • Unlike original GetData, new methods output data via return value, not byref parameter
  • Support one-line code style: Dim Data As String: Data = GetDataText()

Planned new methods:

vb
' Directly return text
Debug.Print Client.GetDataText()                    ' One-line code
Debug.Print Client.GetDataTextUTF8()                 ' UTF-8 text
Debug.Print Client.GetDataTextUnicode()              ' Unicode text

' Directly return hex
Debug.Print Client.GetDataHex()                      ' "48 65 6C 6C 6F"

' Directly return byte array
Dim baData() As Byte
baData = Client.GetDataByteArray()

' Condition check
If Client.GetDataText() = "Hello" Then
    Debug.Print "Received Hello"
End If

' Function call processing
Dim sReply As String
sReply = ProcessData(Client.GetDataText())

Detailed design: See Development Plan


Comparison with Native Winsock Control

FeatureNative Winsock ControlcWinsock Class
Object modelControl array, managed via indexPure class object, direct reference
Event parametersPass index, need reverse lookup objectDirectly pass client object
Client managementManually maintain index and controlsAutomatically manage Clients collection
UDP serverConnectionless, no client conceptVirtual client objects
Connection interceptionNeed to manually close after AcceptEvent parameter control, auto cleanup
Encoding supportFixed encodingMultiple encoding options
Data typesString/byte arrayString/byte array + flexible conversion
Event unificationIndependent event per clientServer triggers all client events uniformly
Resource managementNeed to manually Unload controlsAuto cleanup and garbage collection

Quick Start

TCP Client Example

vb
Private WithEvents m_oClient As cWinsock

Private Sub Form_Load()
    Set m_oClient = New cWinsock
    m_oClient.Protocol = sckTCPProtocol
    m_oClient.Connect "127.0.0.1", 8080
End Sub

Private Sub m_oClient_Connect(Client As cWinsock)
    Debug.Print "Connected to server"
    Client.SendData "Hello, Server!"
End Sub

Private Sub m_oClient_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    Debug.Print "Received data: " & sData
End Sub

Private Sub Form_Unload(Cancel As Integer)
    m_oClient.Close_
End Sub

TCP Server Example

vb
Private WithEvents m_oServer As cWinsock

Private Sub Form_Load()
    Set m_oServer = New cWinsock
    m_oServer.Protocol = sckTCPProtocol
    m_oServer.Listen 8080
End Sub

Private Sub m_oServer_ConnectionRequest(Client As cWinsock, ByRef DisConnect As Boolean)
    Debug.Print "New client connection: " & Client.RemoteHostIP
    ' DisConnect = False means accept connection
End Sub

Private Sub m_oServer_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    Debug.Print "Data from client " & Client.Tag & ": " & sData
    
    ' Echo
    Client.SendData "Echo: " & sData
End Sub

Private Sub m_oServer_CloseEvent(Client As cWinsock)
    Debug.Print "Client disconnected: " & Client.Tag
End Sub

Private Sub Form_Unload(Cancel As Integer)
    m_oServer.Close_
End Sub

UDP Communication Example

vb
Private WithEvents m_oUdp As cWinsock

Private Sub Form_Load()
    Set m_oUdp = New cWinsock
    m_oUdp.Protocol = sckUDPProtocol
    m_oUdp.Bind 8888
End Sub

Private Sub cmdSend_Click()
    m_oUdp.RemoteHost = "127.0.0.1"
    m_oUdp.RemotePort = 9999
    m_oUdp.SendData "Hello, UDP!"
End Sub

Private Sub m_oUdp_DataArrival(Client As cWinsock, ByVal bytesTotal As Long)
    Dim sData As String
    Client.GetData sData
    Debug.Print "Received UDP data (" & Client.RemoteHostIP & ":" & Client.RemotePort & "): " & sData
End Sub

Architecture Design

Class Hierarchy

cWinsock (public class)
    ├── m_oSocket: cAsyncSocket (internal encapsulation)
    ├── m_cClients: Collection (client collection)
    ├── m_oParentServer: cWinsock (parent server reference, clients only)
    └── Events: Connect, CloseEvent, ConnectionRequest, DataArrival, SendProgress, SendComplete, Error

Object Relationship Diagram

Server object
├── Socket (listening socket)
├── Clients collection
│   ├── Client object 1 (cWinsock)
│   │   ├── Socket (independent connection)
│   │   └── ParentServer → Server object
│   ├── Client object 2 (cWinsock)
│   │   ├── Socket (independent connection)
│   │   └── ParentServer → Server object
│   └── ...
└── Event handler
    └── All client data triggered through this

State Machine

sckClosed (0)
    ├─ Connect() → sckResolvingHost → sckHostResolved → sckConnecting → sckConnected (7)
    ├─ Listen() → sckListening (2)
    └─ Bind() → sckOpen (1)

sckListening (2)
    └─ OnAccept → Create client → sckConnected

sckConnected (7)
    └─ OnClose → sckClosed

Error → sckError (9)

Documentation Index

DocumentDescription
Events ReferenceDetailed explanation and usage examples for all events
Property ReferenceDescription, type, and purpose of all properties
Method ReferenceParameters, return values, and usage examples for all methods
Encoding GuideUsage instructions and best practices for text encoding
TCP ProgrammingTCP client and server programming guide
UDP ProgrammingUDP communication programming guide
Best PracticesSolutions for common scenarios and performance optimization recommendations
Development PlanProject development progress tracking and future feature planning

License

Based on VbAsyncSocket (wqweto@gmail.com)


Author

cWinsock: woeoio@qq.com
VbAsyncSocket: wqweto@gmail.com


Last updated: 2026-01-09

VB6 and LOGO copyright of Microsoft Corporation