Click here to Skip to main content
13,288,121 members (53,717 online)
Click here to Skip to main content
Add your own
alternative version


63 bookmarked
Posted 13 Jun 2004

The Ultimate Socket Library

, 13 Jun 2004
Rate this:
Please Sign up or sign in to vote.
All what you need to know about sockets.


Though Microsoft has done a great job wrapping Winsock API, developers are now facing a new challenge; thread-safety and asynchronous calls. Still the developer can get out without handling these issues, soon to realize that the application hangs or behaves unexpectedly due to the server asynchronously replying back, or that the UI will hang till the server responds. The goal of this project is to have a reliable socket library that will serve as a base for all TCP connections; covering most of the common mistakes where others left.

Ways of receiving data

You can receive data in three ways. First, you can block the application thread until a packet has been received, by calling the Receive method of a Socket object. Obviously, this is not a quite good solution for real-world scenarios. The second option is you can go into a loop (busy loop), polling the Socket object to determine if a packet has been received. This is an OK solution except that it will slow down your main application thread every time you tell the socket to poll and wait for a period of time. The third and last option is to receive data asynchronously by telling the socket to BeginReceive data into byte array, and once data has been received, call a special procedure that is set up to receive the data. Of course, by now you can tell what option I’ve chosen.

Working example

In my project, I’ve developed a component where you can just drag and drop into your application and whoo-ya, it's working. Let’s look into how and why it is done in this way.


The first thing you need to do in socket application is to connect to a specific port. There are three overloads of this function for ease of use:

Public Sub Connect(ByVal hostNameOrAddress As String, ByVal port As Int32)
Public Sub Connect(ByVal serverAddress as IPAddress, ByVal port as Int32)
Public Sub Connect(ByVal endPoint As IPEndPoint)

The main function is as follows (error handling in the code snippet is omitted):

Public Sub Connect(ByVal endPoint As IPEndPoint)
    _mySocket = New Socket(AddressFamily.InterNetwork, _
                    SocketType.Stream, ProtocolType.Tcp)
    If IsConnected() = True Then
        RaiseEvent Connected(True)
    End If
    Dim bytes(_packetSize - 1) As Byte
      _mySocket.BeginReceive(bytes, 0, bytes.Length, _
        SocketFlags.None, AddressOf ReceiveCallBack, bytes)
    Catch ex As Exception
      Throw New Exception("Error receiving data", ex)
      If IsConnected() = False Then
        RaiseEvent Connected(False)
      End If
    End Try 
End Sub

After establishing a connection, we raise a connection event which I will illustrate soon; once raised, we declare an array of bytes to receive the data. Now, the first trick is to use the BeginInReceive. This tells the socket to wait for a received data on another thread -a new one- from the thread pool, ha? Rings a bill? Yes. It is asynchronous, now I have my application running and not hanging to receive a packet. The function receives the bytes array which will be filled, its length, socket flag, an address of the callback function, and a state object. The callback function will be called when either an entire packet is received or the buffer is full. Again, if there is any error, a connection event is raised stating that the connection is lost and there were an error in receiving the data.

What about ReceiveCallback

ReceiveCallback function is the handler which will handle the packet when received. This is the core of the asynchronous operation. Take a look at the code and then I will explain.

Private Sub ReceiveCallBack(ByVal ar As IAsyncResult)
    Dim bytes() As Byte = ar.AsyncState
    Dim numBytes As Int32 = _mySocket.EndReceive(ar)
    If numBytes > 0 Then
      ReDim Preserve bytes(numBytes - 1)
      Dim received As String = _ascii.GetString(bytes)
      '--Now we need to raise the received event. 
      '  args() is used to pass an argument from this thread
      '  to the synchronized container's ui thread.
      Dim args(0) As Object
   Dim d As New RaiseReceiveEvent(AddressOf OnReceive)
      args(0) = received
      '--Invoke the private delegate from the thread. 
      _syncObject.Invoke(d, args)
    End If 
    If IsConnected() = False Then
      Dim args() As Object = {False}
      Dim d As New RaiseConnectedEvent(AddressOf OnConnected)
      _syncObject.Invoke(d, args)
      '--Yes, then resize bytes to packet size
      ReDim bytes(PacketSize - 1)
      '--Call BeginReceive again, catching any error
        _mySocket.BeginReceive(bytes, 0, bytes.Length, _
          SocketFlags.None, AddressOf ReceiveCallBack, bytes)
      Catch ex As Exception
        '--Raise the exception event 
        Dim args() As Object = {ex}
        Dim d As New RaiseExceptionEvent(AddressOf OnExcpetion)
        _syncObject.Invoke(d, args)
        '--If not connected, raise the connected event
        If IsConnected() = False Then
          args(0) = False
          Dim dl As New RaiseConnectedEvent(AddressOf OnConnected)
          _syncObject.Invoke(dl, args)
        End If
      End Try
    End If
  End Sub

Now that you’ve gone through the code, what do you think? Don’t worry, I will explain. First, we have a local variable to hold what I received from the server. Then I immediately issue EndReceive which will free any resources used by the BeginRecieve to create a new thread, and so forth. I also resize the array of bytes with the actual size. We, then, declare a local delegate object, and instead of modifying the main application (the user interface, for example) inside this component, it raises an event (Received) via OnReceive method. And since the event is raised on the main thread, it’s completely thread-safe. This is done by calling Invoke method from the private object _syncObject. But what is _syncObject? It is of type ISynchronizeInvoke. Ha? Well _syncObject is used to switch the context from the socket thread to the main thread (in this case, the UI component). This is achieved by having the SynchronizingObject property available to the main control. Here is the code for this property:

Public Property SynchronizingObject() As _
      If _syncObject Is Nothing And Me.DesignMode Then
        Dim designer As IDesignerHost = Me.GetService(GetType(IDesignerHost))
        If Not (designer Is Nothing) Then
          _syncObject = designer.RootComponent
        End If
      End If
      Return _syncObject
    End Get
    Set(ByVal Value As System.ComponentModel.ISynchronizeInvoke)
      If Not Me.DesignMode Then
        If Not (_syncObject Is Nothing) And Not (_syncObject Is Value) Then
          Throw New Exception("Property ca not be set at run-time")
          _syncObject = Value
        End If
      End If
    End Set
  End Property


There are three events and so three delegates:

  • Connections: fires when a connection is opened or the connection is closed.
  • Exception: fires whenever an exception happens.
  • Received: fires whenever a packet is received.


Enough abstract and give me the code, this is how you are thinking right now. This is not yet a full proof library; I think there are still more for this small monster to grow. Hope I got your attention and I will appreciate your feedback.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

The Silence
Web Developer
United Arab Emirates United Arab Emirates
You can check my blog for more information.

You may also be interested in...


Comments and Discussions

QuestionWhy not fully Asynch? Pin
Member 42919069-Sep-15 7:07
memberMember 42919069-Sep-15 7:07 
QuestionSuccessfully converted to VB.NET 2010 but some issue found Pin
Member 944989323-Sep-12 21:58
memberMember 944989323-Sep-12 21:58 
QuestionHow can I post data to web form using sockets Pin
ygodil5-Dec-11 2:39
memberygodil5-Dec-11 2:39 
Hi All,

Is there a way to post a webform automatically using Sockets in c# or I know this can be done using HTTPWebRequest/Response classes, however, I would like to do it with sockets.

Can somebody please provide any help/article or sample code. I would like to see simulating automatic GMail login using sockets.

GeneralMy vote of 5 Pin
Mike Chibaka14-Sep-11 7:08
memberMike Chibaka14-Sep-11 7:08 
QuestionClient crash on lost server connection Pin
WomblingFree13-Sep-11 12:44
memberWomblingFree13-Sep-11 12:44 
AnswerRe: Client crash on lost server connection Pin
WomblingFree13-Sep-11 13:26
memberWomblingFree13-Sep-11 13:26 
Generalvb.Net 2008 Pin
mhozak19-May-10 4:45
membermhozak19-May-10 4:45 
GeneralIncorporating into a Windows Service Pin
ja92810-Oct-08 10:33
memberja92810-Oct-08 10:33 
Questiontranslate to Pin
njudit7-Oct-08 0:02
membernjudit7-Oct-08 0:02 
QuestionWorking in UI, but not in a DLL Pin
Tacho16-Jul-07 11:59
memberTacho16-Jul-07 11:59 
AnswerRe: Working in UI, but not in a DLL Pin
RobertoQueirolo8-Sep-08 9:10
memberRobertoQueirolo8-Sep-08 9:10 
GeneralNeed to return different data to client Pin
Jimbo279833-May-07 2:45
memberJimbo279833-May-07 2:45 
GeneralWas working, is not now Pin
Jimbo279831-May-07 1:36
memberJimbo279831-May-07 1:36 
Questionclientsockets.dll in pocketpc application? Pin
p10n33r15-Nov-06 23:44
memberp10n33r15-Nov-06 23:44 
GeneralServer socket listener for Pin
ajo3827-Sep-06 8:34
memberajo3827-Sep-06 8:34 
GeneralRe: Server socket listener for Pin
SBendBuckeye15-Nov-06 5:47
memberSBendBuckeye15-Nov-06 5:47 
Questionhowcome you are a gold member? Pin
Kedar V10-Jul-06 1:48
memberKedar V10-Jul-06 1:48 
GeneralAsync Socket Example [modified] Pin
howartthou9-Jul-06 18:26
memberhowartthou9-Jul-06 18:26 
GeneralI get an error on form closing. Pin
PsychUK2-Jul-06 2:22
memberPsychUK2-Jul-06 2:22 
GeneralUnicode Support. Pin
PsychUK23-Jun-06 6:56
memberPsychUK23-Jun-06 6:56 
GeneralRe: Unicode Support. Pin
PsychUK2-Jul-06 2:17
memberPsychUK2-Jul-06 2:17 
GeneralNot Responding Pin
reddysuryabhanu8-Jan-06 23:54
memberreddysuryabhanu8-Jan-06 23:54 
GeneralOverloading Send/Recieve Pin
DrewBai5-Jan-06 9:33
memberDrewBai5-Jan-06 9:33 
GeneralRe: Overloading Send/Recieve Pin
The Silence6-Jan-06 8:37
memberThe Silence6-Jan-06 8:37 
QuestionServer is not stopping Pin
frumbert1-Jan-06 18:25
memberfrumbert1-Jan-06 18:25 
AnswerRe: Server is not stopping Pin
The Silence6-Jan-06 8:39
memberThe Silence6-Jan-06 8:39 
GeneralRe: Server is not stopping Pin
frumbert6-Jan-06 22:12
memberfrumbert6-Jan-06 22:12 
GeneralVariable array in BeginReceive Pin
kelphis27-Sep-05 10:31
memberkelphis27-Sep-05 10:31 
GeneralRe: Variable array in BeginReceive Pin
Farhad Shahvir20-Apr-07 23:27
memberFarhad Shahvir20-Apr-07 23:27 
GeneralClient close without TIME_WAIT Pin
dundask14-Sep-05 23:52
memberdundask14-Sep-05 23:52 
GeneralRe: Client close without TIME_WAIT Pin
The Silence15-Sep-05 1:54
memberThe Silence15-Sep-05 1:54 
GeneralRe: Client close without TIME_WAIT Pin
dundask15-Sep-05 19:13
memberdundask15-Sep-05 19:13 
GeneralRe: Client close without TIME_WAIT Pin
Scott Glazier3-Dec-05 21:55
memberScott Glazier3-Dec-05 21:55 
GeneralRe: Client close without TIME_WAIT Pin
Opteron6415-May-09 7:39
memberOpteron6415-May-09 7:39 
GeneraltcpListener Pin
barakiki7222-Aug-05 5:12
memberbarakiki7222-Aug-05 5:12 
Generalurgent pls.. Pin
mm7720-Jun-05 3:13
membermm7720-Jun-05 3:13 
GeneralRe: urgent pls.. Pin
The Silence7-Aug-05 6:43
memberThe Silence7-Aug-05 6:43 
GeneralModule Pin
airomid18-Jun-05 11:51
memberairomid18-Jun-05 11:51 
Generalcan't close the client Pin
mm7725-May-05 23:39
membermm7725-May-05 23:39 
GeneralRe: can't close the client Pin
The Silence27-May-05 7:37
memberThe Silence27-May-05 7:37 
GeneralRe: can't close the client Pin
mm7729-May-05 21:28
membermm7729-May-05 21:28 
GeneralRe: can't close the client Pin
mmclendon21-Dec-06 9:49
membermmclendon21-Dec-06 9:49 
GeneralSystem.Text.ASCIIEncoding Pin
airomid22-May-05 3:13
memberairomid22-May-05 3:13 
GeneralRe: System.Text.ASCIIEncoding Pin
The Silence23-May-05 5:40
memberThe Silence23-May-05 5:40 
GeneralRe: System.Text.ASCIIEncoding Pin
dundask14-Sep-05 21:04
memberdundask14-Sep-05 21:04 
GeneralRe: System.Text.ASCIIEncoding Pin
The Silence15-Sep-05 1:56
memberThe Silence15-Sep-05 1:56 
GeneralRe: System.Text.ASCIIEncoding Pin
dundask15-Sep-05 19:11
memberdundask15-Sep-05 19:11 
General[Message Deleted] Pin
Vitoto4-May-05 8:00
memberVitoto4-May-05 8:00 
GeneralRe: Detect when Client Kill Process ? Pin
The Silence4-May-05 11:14
memberThe Silence4-May-05 11:14 
GeneralRe: Detect when Client Kill Process ? Pin
Anonymous4-May-05 11:21
sussAnonymous4-May-05 11:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 14 Jun 2004
Article Copyright 2004 by The Silence
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid