|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
The following source was built using Visual Studio 6.0 SP5 and Visual Studio .Net. You need to have a version of the Microsoft Platform SDK installed
OverviewAlthough socket based TCP/IP servers using IO Completion Ports are often written in C++ it's sometimes useful to write such a server in Visual Basic. You can use the Winsock control for this, but it deals with the Windows Sockets interface at a very low level and you have to write lots of VB code. This article presents a simple COM object that wraps the high performance socket server framework that we developed in previous articles. The COM object provides a simple, yet powerful, interface that allows you to easily construct high performance TCP/IP servers with a minimal amount of VB code. The article presents the Socket Server COM object and a simple sample VB server application and describes how you use the COM object. The next article will deal with how the COM object was constructed and the design decisions and coding of the object itself. Please note that this object can only be used on Windows NT/2000/XP it does not supportWindows 9x. A high performance TCP/IP Socket Server COM objectThe socket server COM object provides a factory object for creating TCP/IP socket servers. The factory object is
marked as an
Dim server As COMSOCKETSERVERLib.server
Set server = CreateSocketServer(5001)
The code above creates a server that will listen on port 5001. If you have a multi-homed machine then you can optionally specify a single IP address for the server to listen on:
Dim server As COMSOCKETSERVERLib.server
Set server = CreateSocketServer(5001, "192.168.0.1")
Once you have your server object you can start accepting connections by calling Private Sub m_server_OnConnectionClosed(ByVal socket As COMSOCKETSERVERLib.ISocket)
End Sub
Private Sub m_server_OnConnectionEstablished(ByVal socket As COMSOCKETSERVERLib.ISocket)
End Sub
Private Sub m_server_OnDataReceived( _
ByVal socket As COMSOCKETSERVERLib.ISocket, _
ByVal data As COMSOCKETSERVERLib.IData)
End Sub
Notice that each event passes you a The Socket object has two properties: The The final object involved is the An example server in VBAs 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 ShutdownAfterWrite.Value Then
frm.ShutdownAfterWrite = CLng(ShutdownAfter.Text)
ElseIf 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()
ShutdownAfterWrite.Enabled = ShutdownEnabled.Value
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 ShutdownAfterWrite As Integer
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
Dim thenShutdown As Boolean
thenShutdown = False
If ShutdownAfterWrite <> 0 And ShutdownAfterWrite = counter Then
thenShutdown = True
End If
Socket.Write Bytes, thenShutdown
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
Dim thenShutdown As Boolean
thenShutdown = False
If ShutdownAfterWrite <> 0 And ShutdownAfterWrite = counter Then
thenShutdown = True
End If
Socket.WriteString theData, False, thenShutdown
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 Revision history
| ||||||||||||||||||||