Library tutorials & articles

A TCP/IP socket server object for Visual Basic

Page 2 of 4
  1. Overview
  2. A high performance TCP/IP Socket Server COM object
  3. An example server in VB
  4. Wrap up

A high performance TCP/IP Socket Server COM object

The socket server COM object provides a factory object for creating TCP/IP socket servers. The factory object is marked as an "appobject" so you can use it without an explicit reference as in the following example:

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 StartListening and you can stop accepting connections by calling StopListening. It's quite OK to call StartListening again after you have stopped listening - you might do this if you wanted to resume the server after pausing it to prevent it accepting new connections. The server also has a read only LocalAddress property which will return the IP address and port of the server. The main coding for your server occurs in the three event handlers for the events that the socket server fires to inform you of client connection, client data arrival and client disconnection. The events are as follows:

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 Socket object. The socket object represents the connected client socket and provides you with methods and properties to manipulate its state. You can write data to the client in two ways; the Write method allows you to transmit an array of bytes and WriteString allows you to send a string. WriteString takes an optional boolean flag which determines if the string is sent as a UNICODE string or not. Both write methods also take an optional boolean flag that allows you to specify that this is the last write that you will be performing on this socket and that the send side of the socket should be shut down after the write completes. You can read data from the client by using the asynchronous RequestRead method - when the read completes the OnDataReceived event will be fired and you'll be passed the data that was read. When you have finished with the socket you can shut down the connection with the Shutdown method. This allows you to shut down the read and write sides of the connection together or independently. You can also forcibly close the socket with the Close method but beware, this may cause partially transmitted data to be lost.

The Socket object has two properties: The RemoteAddress property provides read only access to the address associated with the client end of the connection. The UserData property provides a place to store your own "per-connection" data, this can be anything you like, but a common use for it would be as a way of associating a class that you use to store session state for the connection. Your user data is stored in the Socket and since you are passed the Socket each time data arrives and when the connection is closed you can retrieve your per session state when ever you need it.

The final object involved is the Data object that you are passed when a read completes and the OnDataReceived event is fired. This has two methods, Read which returns the data as an array of bytes and ReadString which returns the data as a string. Bear in mind that you cannot guarantee to receive data that a client may have sent as a single block with a single call to RequestRead and subsequent firing of the OnDataReceived event. The data may be fragmented into multiple packets and you will need to handle reassembly yourself by making another call to RequestRead and buffering the data yourself. Because of this danger of packet fragmentation, ReadString does not have any way of specifying that the data being read is already a UNICODE string. If your protocol involves sending and receiving UNICODE strings then you must read your data using the Read method and convert from the byte array to a string yourself. This is because it is inherently unsafe to do the conversion below this level due to the potential of packet fragmentation causing the receipt of an incomplete UNICODE character. You can call a combination of Read and ReadString multiple times on the same Data object and you will retrieve the same data each time.

Comments

  1. 11 May 2006 at 16:46

    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.







  2. 18 Sep 2005 at 22:25

    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);

  3. 18 Sep 2005 at 22:22

    I'm afraid I don't have a free version of this code that includes client support.

  4. 18 Sep 2005 at 22:17

    Yes.

  5. 19 May 2004 at 15:09

    may I use this library for a client application? do you have another dll to do this (with vb6)? great job

  6. 18 May 2004 at 17:45
    the function Data.ReadString is not working - any idea? (Data.Read is working normally...) if you type in a terminal it's ok, but if you do a batch the routine stops...
  7. 13 Feb 2004 at 13:32

    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.

  8. 28 Oct 2003 at 04:38

    Does you server support multiple clients connecting simultaneously?

  9. 01 Jan 1999 at 00:00

    This thread is for discussions of A TCP/IP socket server object for Visual Basic.

Leave a comment

Sign in or Join us (it's free).

Len Holgate Len has been programming for over 20 years, having first started with a Sinclair ZX-80. Now he runs his own consulting company, JetByte Limited. JetByte provides contract programming and consultanc...

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

We'd love to hear what you think! Submit ideas or give us feedback