Library tutorials & articles
A TCP/IP socket server object for Visual Basic
- Overview
- A high performance TCP/IP Socket Server COM object
- An example server in VB
- Wrap up
An example server in VB
As a simple example we will develop an echo server that stores some per-connection state and can optionally shut down the connection in a variety of ways after echoing a certain number of data packets.
Our echo server consists of two forms. The first allows you to specify the port that the server should listen on and also set some parameters. When a server is created the second form is displayed, this contains a list control and handles the events that the server fires. After creating a server you can switch back to the first form, change the port number and create another server. All servers can operate independently.
The code behind the first form is fairly simple and mostly consists of managing the user interface elements and passing parameters to the second form. The work required to create the socket server itself is very simple.
Option Explicit
Private Sub Command1_Click()
Dim server As JBSOCKETSERVERLib.server
Set server = CreateSocketServer(CLng(Text1.Text))
Dim frm As Form2
Set frm = New Form2
frm.SetServer server
frm.ShowDataPackets.Value = ShowDataPackets.Value
frm.DataIsBytes.Value = DataIsBytes.Value
frm.DataIsString.Value = DataIsString.Value
frm.SignOnAsUnicode.Value = SignOnAsUnicode.Value
If ShutdownEnabled.Value Then
If ShutdownSocket.Value Then
frm.ShutdownAfter = CLng(ShutdownAfter.Text)
ElseIf CloseSocket.Value Then
frm.CloseAfter = CLng(ShutdownAfter.Text)
End If
End If
server.StartListening
frm.Show , Me
End Sub
Private Sub ShowDataPackets_Click()
DataIsFrame.Enabled = ShowDataPackets.Value
DataIsBytes.Enabled = ShowDataPackets.Value
DataIsString.Enabled = ShowDataPackets.Value
End Sub
Private Sub ShutdownEnabled_Click()
ShutdownSocket.Enabled = ShutdownEnabled.Value
CloseSocket.Enabled = ShutdownEnabled.Value
ShutdownAfter.Enabled = ShutdownEnabled.Value
End Sub
The second form is slightly more complex. The code that handles the socket server is as follows:
Option Explicit
Dim WithEvents m_server As JBSOCKETSERVERLib.server
Public ShutdownAfter As Integer
Public CloseAfter As Integer
Private ListWidth As Integer
Private ListHeight As Integer
Public Sub SetServer(server As JBSOCKETSERVERLib.server)
Set m_server = server
Caption = "Socket server listening on: " & server.LocalAddress.Port
End Sub
Private Sub m_server_OnConnectionClosed(ByVal Socket As JBSOCKETSERVERLib.ISocket)
If ShowDataPackets.Value Then
AddToList "OnConnectionClosed : " & GetAddressAsString(Socket)
End If
Dim counter As Class1
Set counter = Socket.UserData
If ShowDataPackets.Value Then
AddToList "User data = " & counter.GetCount()
End If
Socket.UserData = 0
End Sub
Private Sub m_server_OnConnectionEstablished(ByVal Socket As JBSOCKETSERVERLib.ISocket)
If ShowDataPackets.Value Then
AddToList "OnConnectionEstablished : " & GetAddressAsString(Socket)
End If
Dim counter As Class1
Set counter = New Class1
Socket.UserData = counter
Socket.WriteString "Welcome to VB echo server" & vbCrLf, SignOnAsUnicode.Value
Socket.RequestRead
End Sub
Private Sub m_server_OnDataReceived( _
ByVal Socket As JBSOCKETSERVERLib.ISocket, _
ByVal Data As JBSOCKETSERVERLib.IData)
Dim counter As Class1
Set counter = Socket.UserData
counter.IncrementCount
If DataIsBytes.Value Then
OnReceivedBytes Socket, Data, counter.GetCount
ElseIf DataIsString.Value Then
OnReceivedString Socket, Data, counter.GetCount
End If
Socket.RequestRead
If ShutdownAfter <> 0 And ShutdownAfter = counter.GetCount Then
Socket.Shutdown ShutdownBoth
End If
If CloseAfter <> 0 And CloseAfter = counter.GetCount Then
Socket.Close
End If
End Sub
Private Sub OnReceivedBytes( _
ByVal Socket As JBSOCKETSERVERLib.ISocket, _
ByVal Data As JBSOCKETSERVERLib.IData, _
counter As Integer)
Dim Bytes() As Byte
Bytes = Data.Read()
If ShowDataPackets.Value Then
Dim stringRep As String
Dim i As Integer
For i = LBound(Bytes) To UBound(Bytes)
stringRep = stringRep & CLng(Bytes(i)) & " "
Next i
AddToList "OnDataReceived : " & GetAddressAsString(Socket) & " - " & stringRep
End If
Socket.Write Bytes
End Sub
Private Sub OnReceivedString( _
ByVal Socket As JBSOCKETSERVERLib.ISocket, _
ByVal Data As JBSOCKETSERVERLib.IData, _
counter As Integer)
Dim theData As String
theData = Data.ReadString
If ShowDataPackets.Value Then
AddToList "OnDataReceived : " & GetAddressAsString(Socket) & " - " & theData
End If
Socket.WriteString theData, False
End Sub
Private Function GetAddressAsString(Socket As JBSOCKETSERVERLib.ISocket) As String
GetAddressAsString = Socket.RemoteAddress.Address & " : " & Socket.RemoteAddress.Port
End Function
The code is made more complex by the fact that we can display and echo the data and shut down the connection in all of the possible ways. Notice how we initialise our user data in the m_server_OnConnectionEstablished event and store it in the Socket. We then retrieve and use it in the m_server_OnDataReceived and m_server_OnConnectionClosed events.
Related articles
Related discussion
-
Flex 3 Component Solutions: Build Amazing Interfaces with Flex Components
by matquy_kyo22 (0 replies)
-
Java - Closing inputstream causes socket to close
by led1433 (1 replies)
-
How to POP3 in C#
by bishnu.tewary (7 replies)
-
The "Easy Installer" from JoomlaTag
by msecure32 (0 replies)
Related podcasts
-
Java Posse #206 - Newscast for Sept 17th 2008
Newscast for Sept 17th 2008Fully formatted shownotes can always be found at http://javaposse.com Java complexity again, but from a different angle:http://forums.java.net/jive/thread.jspa?messageID=298125&tstart=0#298125 JVM Language summit - the details emergehttp://openjdk.java.net/project...
I ran the server on one machine and the client on another and managed to get a connection and send some data. However after sending a few test messages "1234567890" I try and receive as string at the other end and it stops working. I put in extra calls in the event handlers and they don't get called. The sender thingks it has sent the data. The only way I can stop it is to open the connection again and then press send. Any ideas?
Also when I close down the server, Windows2000 server won't let me delete the file even though it is not in the process list - is there some resource that needs closing in the code somewhere on exit?
I am trying to get a reliable point to point comms for sending some string data.
Ross D.
There was a stupid precedence error in the original code, this may be related to it?
LPOLESTR pOle = ((lpa = (char*)mpData) == NULL) ? NULL : ATLA2WHELPER((LPWSTR) alloca(mlength + 1*2), _lpa, mlength);
should be
LPOLESTR pOle = ((lpa = (char*)mpData) == NULL) ? NULL : ATLA2WHELPER((LPWSTR) alloca((mlength + 1)*2), _lpa, mlength);
I'm afraid I don't have a free version of this code that includes client support.
Yes.
may I use this library for a client application? do you have another dll to do this (with vb6)? great job
There're several useful Winsock tutorial on this site... But its not detailing enough considerations in helping newbie extend the tutorial into actual application environment. One of them is providing a tutorial on preventing reentrancy when working high socket traffic scenario.
Typical Winsock application logic when data arrives...
1. The Winsock_DataArrival event fires when client sockets send data to the listening socket server
2. On Data Arrival, Inspect the data received
3. Process the data received (e.g. Lookup Databases, Refresh GUI, and others)
When multiple data stream or even large chunk of data arrive while your code is Processing "time-instensive" routines/tasks will require u to implement a FIFO buffer into your code to ensure all incoming data are captured and processed properly... I'm pleading for the community to add this logic to existing tutorial or post some sample code. Thanks in advance.
Does you server support multiple clients connecting simultaneously?
This thread is for discussions of A TCP/IP socket server object for Visual Basic.