MESockets.dll

Namespace:  MacyEnt.sockets.MESkt

 

 

 

 

 

Distribution. 2

Description. 2

Unicode and ANSI Considerations. 2

Constructors. 3

Properties. 3

Methods. 3

Parameters. 4

Errors Thrown. 4

Sample Code. 4


 

Distribution

The distribution consists of the DLL, a test application and project, and this file.   To test the class when you have unzipped everything into an application folder, run two instances of the test application.  Define one as a server by entering a port number (i.e. 4000) and pressing the Start As Server button.  Define the other as the client by entering the same port number and the name of your workstation (localhost in some cases) in the Client’s Server’s Name field and press the Start As Client button.  Enter data into the client’s Data field.  Press the server’s Receive button.  Press the client’s Send button.   The data should show up in the server’s data field.  You can now send data back and forth remembering that a Send requires a Receive by the partner.  If this does not work, an error will show up in the error text window.  This is possibly due to firewall protection.

 

Files in this distribution:

·        MESkt.sln – Visual Studio Solution with test form

·        MESkt.suo

·        Documentation\MESocket.chm – Compiled HTML of this file.

·        MESkt_Test\AssemblyInfo.vb – MESkt_Test is the test project

·        MESkt_Test\Form1.vb

·        MESkt_Test\MESkt_Test.vbproj

·        MESkt_Test\MESkt_Test.vbproj.user

·        MESkt_Test\bin\ckeckTrialClass.dll – Used to track use of trial version

·        MESkt_Test\bin\MESockets.dll – The ME Socket DLL.

·        MESkt_Test\bin\sktTrial.me – Required by the trial version. Should exist in folder from where application is run.

·        MESkt_Test\bin\socketTest.exe – The test application.  Run this EXE.

 

Description

An instance of this class provides

  1. simplified use of sockets
  2. timeouts
  3. large messages

 

Implementation is in one class.  (The trial version requires an additional data file.)  Socket use is simplified by providing methods to setup as server or client, read, write, and close.  Socket calls such as the Listen, Accept, and Connect are hidden from the user as is port handling.   While socket protocol is not complicated and the use of the Microsoft socket component simplifies sockets, using the socket classes as provided still requires implementation of timeouts and code to handle the concatenation or parsing of received data to break an input stream into discreet messages.  This is also handled by the MESockets component.

 

This implementation assumes, but does not require, 2-way application communication where a received message is acknowledged before the next is sent.  Socket protocol buffers received data and returns ALL available data to the caller in response to a receive call.  This can be more than a single message if messages are not acknowledged and sent w/o a response.  Or the received data can be less than a complete message due to buffer size limitations or partial message receipt.  Since message application acknowledgement is specified as part of application design, this implementation will return a complete message and only a complete message.  Transparent to the user, this class includes a length header at the front of the message if the hsend method is used. 

            Header:  <0>length<255>

as ANSII bytes where length is the ASCII representation.  The send method sends without a header.  This will work for messages shorter than the TCPIP buffer, which is usually between 1000 and 2000 bytes long.

 

Testing

Testing can be done by running the socketTest.exe two times, once as the client and once as the server. The solution can be run in visual studio as well.

 

During testing, the Start as Server button may cause an error.  This is usually due to not gracefully terminating previous testing or setup.  Try clicking the button a second time.

Testing and Firewalls

From Control Panel, select the Windows Firewall program to run.  The following screen will appear.  For security reasons, the On radio button should be selected.  But this requires that the port being used in an application’s socket program must be listed here as an exception.

 

 

 

Select the exceptions tab and the following screen appears.  Click the Add Port button to add a socket exception – in this case, testSockets was was added.

 

 

 

Editing the testSockets exception and adding it as a port both show the following screen:

 

 

 

By pressing the Change Scope button, a list of acceptable users can be specified for the port.

 

 

For testing purposes, enter 127.0.0.1 which is the default address for a standalone workstation.  Note that the /255.255.255.255 will be added by the firewall logic.

 

Unicode and ANSI Considerations

When integrating across a number of different environments, one of the platforms may use only the Ansi character set and NOT the 16-bit Unicode character set now being used on the Microsoft platform.   The VB BSTR type is Unicode by default.   VB applications written will usually be based upon Unicode unless special steps are taken to code in Ansi.    When input from or output to Ansi based systems such as the DEC environment, care must be taken to assure that Ansi environments don’t see Unicode, and that Unicode environments don’t get passed Ansi unexpectedly.    Conversions must be done between the environments.  Problems can arise when ANSI strings are read into Unicode strings without the proper Encoding being done.

 

To accommodate connections with “ANSI” systems, the communication is done through byte arrays so that Unicode characterization doesn’t cause problems.    However, the using application must still know whether or not communicated arrays are ANSI or Unicode.  For example, the application must use the Encoding Methods to convert strings to ANSI character strings prior to sending to ANSI systems such as a VAX. 

 

An easy way to define a module that will receive from or send to both Unicode and ANSI systems is to always convert strings to ANSI arrays prior to sending.  The receiving application must them convert them back to Unicode if Unicode is required on the receiving platform.   As long as Unicode is NOT required, for example communication of Japanese characters, then this design is not a problem. 

Constructors

Dim mobjSkt As New MACYENT.Sockets.MESkt()

 

Properties

ConnectionActive – True if object is connected to a partner, else False.

Methods

Sub serverSetup(ByVal port As Integer)

 

Sub clientSetup(ByVal serverName As String, _                                         

                           ByVal port As Integer)

 

Sub send(ByRef txtSend( ) As Byte, _

                ByVal byteLength As Long, _

                ByVal timeoutMS As Long)

 

Sub hsend(ByRef txtSend( ) As Byte, _

                  ByVal byteLength As Long, _

                  ByVal timeoutMS As Long)

 

Sub receive(ByRef bytesReceived As Long, _

                    ByVal bytesAvailable As Long, _

                    ByRef txtReceived( ) As Byte, _

                    ByVal timeout As Long)

 

Sub closeConnection( ByVal closeType as Byte )

 

If desired, use send for short messages containing character data.  The hsend method may be used for any message.

 

Parameters

 

 

Port

Socket port number.   For example, 1030.   Standard Internet port is 80.

 

timeout

Time in seconds to listen before timing out.   Maximum value is 86399 seconds  (24 hours minus 1 second).

 

closeType

Clients always close with a closeType=1.  A server will use closeType=1 until an error occurs.  Then the server should use closeType=2 to close the Listening port and start over.

 

Errors Thrown

    sktLostConnection = vbObjectError + 512 + 1

    sktNoSocket = vbObjectError + 512 + 2

    sktSendTimeout = vbObjectError + 512 + 3

    sktRecvTimeout = vbObjectError + 512 + 4

    sktZeroLength = vbObjectError + 512 + 5

    sktInvalidClose = vbObjectError + 512 + 6

    sktInterrupted = vbObjectError + 512 + 7

    SocketException

    ArgumentNullException

    NullReferenceException

 

Sample Code

    Dim mobjSkt As New MACYENT.Sockets.MESkt()

    Dim mobjEncoder As Encoding()

    Dim lc As Integer = MACYENT.Sockets.MESkt.sktLostConnection

    Dim ns As Integer = MACYENT.Sockets.MESkt.sktNoSocket

    Dim st As Integer = MACYENT.Sockets.MESkt.sktSendTimeout

    Dim rt As Integer = MACYENT.Sockets.MESkt.sktRecvTimeout

    Dim zl As Integer = MACYENT.Sockets.MESkt.sktZeroLength

    Dim ic As Integer = MACYENT.Sockets.MESkt.sktInvalidClose

 

    Try

        ' Define self as Server and wait for connection from client

  mobjSkt.serverSetup(4050)

 

        ' Receive a message

        mobjSkt.receive(llngByteReceived, 100, lbytSktArray, 10000)

        dataTextBox.Text = Encoding.ASCII.GetString(lbytSktArray)

        lenTextBox.Text = llngByteReceived

 

            ' Send a short message (in this case an ACK)

        lstrDataMessage = “ACK”

        lbytSktArray = Encoding.ASCII.GetBytes(lstrDataMessage)

        mobjSkt.send(lbytSktArray, UBound(lbytSktArray) + 1, 10000)

 

 

            ... Define lstrLongMessage

 

        ' Send a long message

        lbytSktArray = Encoding.ASCII.GetBytes(lstrLongMessage)

        mobjSkt.hsend(lbytSktArray, UBound(lbytSktArray) + 1, 10000)

 

  ' Close this conversation’s port

        mobjSkt.closeConnection(1)

       

    Catch excp As Exception

        errTextBox.Text = excp.ToString

        mobjSkt.closeConnection(1)

 

  ' Close the connection listening port

        mobjSkt.closeConnection(2)

 

    End Try