NetSimple
CapeSoft Logo

CapeSoft NetTalk
NetSimple

Download Latest Version
Installed Version Latest Version

NetTalk NetSimple

Available in NetTalk Desktop, NetTalk Server and NetTalk Apps. Applies to Desktop (ABC or Clarion) apps.

Introduction

NetSimple is the root of many other classes  in NetTalk. Fundamentally it allows data to be sent by one program and received by another. At this level nothing is added to the data - what goes out this side comes in the other side, and vice versa.

Most methods of communicating data on the internet add a Protocol on top of this raw data transfer. For example Email has SMTP and POP3, the web has HTTP and so on. Those protocols describe the contents of the data being transferred, but underneath it all NetSimple does the actual job of transferring the packets.

NetSimple starts with the simple concept of a Server and a Client. The only distinction here is which one creates the connection. A Client is the one responsible for connecting to the server. Once they are connected then either can send data, both receive data from the other, and either end can close the connection. Again it is the job of the protocol to determine what they send and how they respond or behave when data is received.

TCP/IP does not have a "one packet sent, one packet received" approach. In fact the exact opposite is often the case. The sending computer, or any other computer in the chain, can  choose to split packets apart into multiple smaller packets, or can join packets together. So each end has to think of the data as a "stream" not as "packets".

Therefore ultimately every connection has to have a protocol of some kind so that both ends can easily communicate. It may be really simple but each end needs to know when the other is "finished talking". So it might be something as simple as ending each outgoing stream with a CR/LF. When the receiver receives this they know they have a complete packet, and they start processing it. If they get some data, but not this end-of-text marker then they store that away, and wait for more.

It should be obvious that both the server and client need to be using the same protocol or the system cannot work.

Naturally that protocol has limitations (for example you can't send binary data, or indeed any data that contains a CR/LF) so more sophisticated protocols are often used. HTTP is the most common of these and today many communications sit on top of HTTP rather than use NetSimple directly.

NetSimple includes support for the simplest of protocols, a length is prepended to each outgoing stream. The receiver gets the length, and thus knows how many bytes to expect before they can process incoming data. This is known (by NetTalk) as the WholePacket protocol. It can (almost) only be used when you control both the client and the server. In rare cases you may encounter a server, or client, which also uses this simplest of protocols, but there is no formal standard for this so that is purely accidental. Nevertheless WholePacket can simplify communications for you back into a "one packet out, one packet in" at the application level for you.

UDP

Almost everything (you do) on the internet is based on the Transmission Control Protocol (TCP). There is however another networking protocol called User Datagram Protocol (UDP). UDP is different to TCP in a number of very fundamental ways and is mostly used for infrastructure - things like DNS, SNMP, DHCP and so on.

NetSimple supports creating a UDP client or server, although there's really no distinction between the two. Indeed a UDP NetSimple object is always both a server and a client.

UDP is different to TCP because there is no "connection" created between the client and the server. Rather packets are simply "just sent" from one machine to another. Since there's no connection to open there's no distinction between a server and a client, so UDP objects are always "servers". They are always listening and have the capability to send to any address (on the LAN). [1]

Another difference is delivery. TCP packets are "guaranteed delivery" or an error is generated. UDP packets are not. You send them, but it's possible for them to get "lost" before they get to the destination machine. This makes them useful for a single-packet question with a single packet response, but pretty useless for larger requests and responses. [2]

In an application the code you use to send, and receive, packets via UDP is the same as for TCP. The only difference is that TCP connections need to be Opened (by the client) and UDP connections do not.

Notes
1.  UDP packets seldom travel outside of the LAN, unless specifically allowed to do so by the firewall. It's reasonably safe to assume that for purposes of your own work you should consider UDP to be a LAN-Only protocol, unless your users are specifically able to alter settings in their Firewalls and Routers.

2. In some cases packets are time-sensitive, if they get lost it's no big deal because another is going to be sent anyway. For example a sensor reading outside temperature may just send a UDP packet from time to time. If some packets get lost it's no big deal. Or consider real-time video. Since each frame of the video is only valid for a very short (sub second) amount of time it's possible to simply ignore missing packets, but the time they would be recovered and resent they would be obsolete.

Windows

All NetTalk objects are asynchronous. This means they are event driven, and require an ACCEPT command loop to get events. ACCEPTs in Clarion are related to Windows, so all NetTalk objects (including NetSimple, and all objects derived from NetSimple) require that a window be open, and events flow through the object's TakeEvent method.

You can of course hide the Window so that the user never sees it. This has the effect of making the communications appear to be synchronous in your application. This can have detrimental effects on the program UI though so should be used judiciously.

Ports

As you may know computers on the network are identified with an IP address. Of course there may be many programs on that computer listening for network traffic, so there needs to be a mechanism to identify what network traffic goes to what program. This is done by using a Port Number.

Only one program can be listening at a time to a specific IP Address : Port combination. If the IP address of this machine is 192.168.0.1, and program.exe is listening on Port 1000, then it, and only it, will receive the network traffic directed at 192.168.0.1 port 1000. If a program attempts to listen on a port that is already being occupied by another program then an error will be generated.

Protocols are independent of port number. A web server can thus listen for HTTP traffic on any port it's set to use. However most protocols have a default port number to make it easier for a client to find a server. Common protocols are assigned a default port in the range 0-1024. For example the default port for HTTP is port 80, and the default for HTTPS is 443.

Since 0-1024 are "reserved" for known protocols, if you are making your own NetSimple Server it is recommended you use a port in the range 1025 to 32768.

Packet

Data can be sent from a client to a server, or from a server to a client. It would be very inefficient to send the data one byte at a time, so to avoid that a block of data is sent at once. This block is known as a packet.

The Packet property in the class is a group of type Net:SimplePacketType. This allows you set a number of properties about the data, as well as the data itself. While the packet contains a number of properties the most important ones are;
PropertyDescription
BinDataA string (max size 16K) which contains either text or binary data
BinDataLenThe length of the data placed in BinData. Since BinData can contain any binary data the length needs to be explicitly set.
ToIP
OnSocket
SockID
Used by the server (only) to send packets to a specific client. A server may have multiple clients connected to it at the same time.
PacketTypeReceiving only. One of NET:SimpleNewConnection, NET:SimpleIdleConnection, NET:SimplePartialDataPacket, NET:SimpleWholeDataPacket (only when Whole Packet Protocol is on.)

JumpStart

  1. Add the NetTalk and StringTheory Global Extensions to the application.
  2. Add a "Include NetTalk Object" local extension to the (window) procedure.
  3. On the local extension, General Tab, set the base class to NetSimple. Set the object name to be anything you like. If you add multiple NetTalk objects to the window (which you can do) then make sure each has a unique object name for the procedure. In this JumpStart the object will be called net.
  4. On the settings tab set the object to be a Simple Server, a Simple Client or a UDP Server.
  5. If this is a server you are responsible to open and close the port at the appropriate times. (ie Open it when you are ready to start listening, and Close it when you are done listening.)  For example, to listen on port 2000;

    net.open('',2000)

    It is closed with

    net.close()
  6. If this is a client you are responsible to open the connection to the server before communication can take place. (ie Open the connection when you are ready to start talking.)

    net.open(ServerIPAddress,2000)

    You can also close the connection.

    net.close()

    Alternatively the server may close the connection, in which case the ConnectionClosed method will be called.
  7. Once a connection is open between a client and a server then either side is able to send a packet to the other. A packet is constructed by setting various fields. Once the packet is constructed it is sent using the Send method.

    Example for a client;

    clear(net.packet)
    net.packet.bindata = 'some data'
    net.packet.bindatalen = len(clip(self.packet.bindata))
    net.Send()


    The client does not need to set any other properties in the packet. The data will automatically be directed to the server which is currently connected to.

    Example for a server;

    clear(net.packet)
    net.packet.bindata = 'some data'
    net.packet.bindatalen = len(clip(self.packet.bindata))
    net.ToIP = someIPAddress
    net.packet.OnSocket = someSocketNumber
    net.packet.SockID = someSockIDNumber
    net.Send()


    The server needs to identify the client being sent to, because multiple clients can be connected to the server at the same time. The three identifying values (ToIP, OnSocket and SockID can be retrieved from incoming packets, or when connections are opened. See below for more on this.)
  8. When one end of the connection sends a packet then it will arrive at the other end in the Process method. Remember that one packet sent does not necessarily mean one packet received. A single outgoing packet may be split into multiple incoming packets or vice versa. At the NetSimple level you will need to cope with checking and buffering (if necessary) incoming packets yourself. In the Process method the various Packet properties again come into play.

    An important packet property here is self.packet.packetType. This can be set to one of;
    • NET:SimpleNewConnection - a new connection has been established, there is nothing in BinData
    • NET:SimpleIdleConnection - The connection has been idle for a period of time.
    • NET:SimplePartialDataPacket - A data packet has arrived.
    • NET:SimpleWholeDataPacket - Only if the Whole Packet mode is on, a completed set of packets is now ready for processing.

WholePacket


If you are creating both the server side, and the client side, of the NetSimple connection [1], and you are choosing to not use a standard protocol (like HTTP) then you can make use of the NetTalk WholePacket Protocol (WPP) to simplify packet management.

WPP works by prepending a Long to the front of each packet, to specify the length of that packet. When the receiver gets that many bytes then it knows a "whole packet" has arrived, and it can be processed.

To use the WholePacket protocol use the NetWholePacket class instead of the NetSimple class. This class works exactly the same as the NetSimple class with the exception that incoming (complete) packets are passed to the PacketReceived method. [2] You should put your processing code in here, rather than in the Process method.

The incoming (whole) packets are in the WholePacket property, so in the PacketReceived method you can use this to process the contents of the incoming packets. This property is a StringTheory object so can be of any length. All the StringTheory methods are available at this point, including GetValue() and Length().



Notes.

1.  Some other developers and devices make use of the same technique. If you are interacting with a device that uses this technique then you are in luck. The only complication may be the "order" of the bytes inside the Long. NetTalk uses the Windows order (known as LittleEndian). If the device, or service, you are connecting to uses BigEndian (The bytes are in the reverse order) then you can set the property UseBigEndian to true. You can also control whether the length value in the header includes the header or not using the LengthInclusive property.

2. WholePacket functionality has been refactored in NetTalk 10. If you are upgrading from an earlier NetTalk, and already using the WholePacket functionality then you will get compile errors. See the Upgrading section in this document for details on changes required to your code. these changes are minor and should not take long to apply.

Debugging

Upgrading to NetTalk 10

NetSimple

Some small naming changes have been made to the NetSimple class which may affect your embed code.

WholePacket

The WholePacket functionality has been refactored to make it easier to use, and more consistent with the other classes. If you are using WholePacket functionality in your program then you will need to tweak your code as described below. The changes have been carefully engineered to generate compile errors, so once your program compiles error free then all the necessary changes should have been made.
  1. The WholePacket functionality has been removed from the Netsimple class and moved to its own class, NetWholePacket. If you have an object, using NetWholePacket then change the class it uses from NetSimple to NetWholePacket.
  2. Whole packets used to flow through the Process method, with a packet type set to NET:SimpleWholeDataPacket. The code in here should be moved to the PacketReceived method. This method is only called when a complete packet arrives.
  3. The use of WholePacketQueue.WholeBinData and WholePacketQueue.WholeBinDataLen in PacketReceived has changed. You should now use self.WholePacket.GetValue() and self.WholePacket.Length()
  4. The WholePacketSend method has been renamed to Send.
  5. The WholePacketUseLengthField has been renamed to UseWholePacket. Instead of setting this to 1, or true, it should be set to netWPP:LengthPrefix.
  6. WholePacketUseBigEndian property renamed to UseBigEndian
  7. WholePacketLengthInclusive property renamed to LengthInclusive

FAQ

Class Reference

_NetAll

Included in NetTalk Desktop

The NetAll class is the root class which underpins all the other classes. It is not designed to be used as an object by itself, rather it provides some utility methods which are used by the other classes. All NetTalk objects have these properties and methods.

Properties

PropertyDescription
ErrorContains the Error number of the last error, cleared when next big method is called
ErrorStringContains the Error String of the last error
LoggingOnSet in the constructor if logging is on
LoggingErrorsOnlySet in the constructor if errors logging (only) is on
SSLErrorUsed when self.Error = ERROR:ErrorStoredInSSLError
UseThisThreadAllows you to specify the thread which must receive the event messages. Allows an object on one thread to send messages to another thread. For advanced users only.
WinSockError Used when self.Error = ERROR:ErrorStoredInWinSockError

Methods

MethodDescription
CreateFolderCreates a folder by iterating down the folder creating each step along the way. Supports both c:\ and \\ naming schemes.
GetElapsedTimeUTCReturns a REAL containing the milliseconds elapsed since a date up until now. The default date is 1 January 1970 00:00:00, which is the start of the UNIX Epoch. The time zone is always UTC, regardless of the local system time zone. Used in various places where a single value timestamp is needed.
InterpretErrorProvides a text interpretation of the error number.
LogSends a string to DebugView if LoggingOn is true (or LoggingErrorsOnly is true and this is an error.)
StartReturn the object to a virgin state as if it had just been created.
TraceSend a string to Debugview. Used for debugging purposes.

CreateFolder

CreateFolder (String pFolder)

Description

Creates a folder, as well as parent folders if necessary. Supports both local drive (c:\) and network drive (\\server) naming schemes.

Parameters

ParameterDescription
pFolder
(String)
The name of the folder to create. No filename should be included in this string.

Return Value

The method returns a net:ok if successful.


GetElapsedTimeUTC

GetElapsedTimeUTC (Long pBaseDate=61730)

Description

Returns a REAL containing the milliseconds elapsed since a date up until now. The default date is 1 January 1970 which is the start of the UNIX Epoch.

The time zone is always UTC, regardless of the local system time zone.

Used in various places where a single value timestamp is needed.

Unix / Linux time is measured in seconds, so to convert this value to Linux time divide the result by 1000.

Parameters

ParameterDescription
pBaseDate
Long
A Clarion Standard Date value. The start date of the period. Defaults to Jan , 1970.

Return Value

The method returns a real representing the number of milliseconds since the start date.

See Also


InterpretError

InterpretError ()

Description

Returns a STRING containing a text message for the value currently in the Error property.

Log

Log (String p_FunctionName, String p_LogString, Long p_ErrorType=0)

Description

Sends an error message to Debugview, depending on the values in the LoggingOn  and LoggingErrorsOnly properties.

Return Value

The method returns nothing

See Also

Trace

Start

Start ()

Description

Returns all the properties of the object back to their virgin state. This is useful when reusing a object and you don't want one use to flow into the next use.


Trace

Trace (String p_String)

Description

Sends the p_String value to Debugview. The line will be prefixed with
[netTalk][thread=n]
where n is the current thread.

See Also

Log

NetSimple

Included in NetTalk Desktop

Derivation

  • NetSimple
    • _NetAll ( NetAll.Inc / NetAll.Clw )

Properties

PropertyDescription
AsyncOpenBusy
(long)
An open request is currently underway.
AyncOpenUse
(long)
If true (the default) then opening connections is an asynchronous operation. Definitely recommended.
AsyncOpenTimeout
(long)
The amount of time to take before an Open is considered to have failed. The default is 900 (9 seconds). It's safe to say that if the connection has not been established in this time, then it is not going to connect.
Error
Long
Contains the error value of the last transaction. 0 = no error. You can use the InterpretError() method for converting the error code into an error string. See also self.SSLError and self.WinSockError
ErrorString String(256)Contains the last error string that was reported.
Will only be updated after the parent.ErrorTrap call in the ErrorTrap method.
InActiveTimeOut longThis is length of time in hs (hundredths of a second) after which an idle connection will timeout. When the timeout occurs a packet of packettype NET:SimpleIdleConnection will be sent to .Process()
OpenFlag
Long
This property should be treated as Read-only.
Client Use:
When False the connection is not established. When True the connection is established.
See also the AsyncOpenBusy property to determine if a connection is busy opening in asynchronous mode.

Server Use:
When False the object is not listening on the port. When true the object is listening on the port.
OutgoingDLLPackets
long
After you call the GetInfo() method, this is the number of packets sitting in the NetTalk DLL for this socket connection that are waiting to be sent. It gives you an indication of how much data still needs to be sent. It cannot be used as a confirmation that all packets have been sent. It just means the packets have been sent to WinSock as they may still be in transit. Can be helpful when calculating progress bars for data being sent.
Packet Group
(Net:SimplepacketType)
Used for sending and receiving data. For the components of this group see Net:SimplePacketType.
qServerConnections
Net:SimpleServerConnectionsQType
Server Mode Only: This queue contains the information about all the connections that are connected to the listening port. See the definition of the Net:SimpleServerConnectionsQType Queue.
(Not meaningful in UDP mode)
ServerConnectionsCount
long
Server Mode Only: Indication of how many connections there currently are to the listening port.
(Not meaningful in UDP mode)
SSL
Long
Set this to 1 to use a TLS (formally known as TLS) connection. Defaults to false. For more on TLS connections see [xxxxx]
SSLCertificateOptions
Net:SimpleSSLCertificateOptionsType
Options for the SSL Certificates and Certificate Verification.
For the components of this group see Net:SimpleSSLCertificateOptionsType.
SSLMethod
Long
The method for the TLS connection to use. (TLS 1.2, TLS 1.1 and so on). For more on TLS Methods see [xxx].
SSLDontConnectOnOpen
Long
By default (false) the TLS connection will perform the switch to TLS mode as the connection is opened.
Set this to true if you want to suppress this. In this case the connection will only change to TLS mode when you call the SwitchToSSL method.
SuppressErrorMsg
Long
If this is set to true then ErrorTrap will not automatically trigger a MESSAGE command. If set to false (the default) then it will automatically display all calls to ErrorTrap to the user.
  
  
  
  

Methods

MethodDescription
  
  
  
  
  
  
  
  
  

Done

Done (Long pMessageId)

Description

This method is called after a request to the server completes. The MessageId parameter indicates which message has just been completed. The location of the results will depend on the method that has been called.

Parameters

ParameterDescription
MessageIDThe MessageID of the request which has just completed.

Notes

This is where most of your embed code will go, handling the results of the requests you have made.

Return Value

The method returns nothing.

See Also

ErrorTrap, ValidateUser, GetAttributes, UserInGroup

NetWholePacket

Included in NetTalk Desktop

Derivation

  • NetWholePacket
    • NetSimple ( NetSimp.Inc / NetSimp.Clw )
      • _NetAll

Properties

PropertyDescription
LengthInclusive
Long
Include the length of the header in the header length value. This can be useful to align this class with other devices which do (or don't) include the length of the header in the header. By default this value is false.
UseBigEndian
Long
Set the length header to use BigEndian format. By default this value is false. Tis can be useful to align this class with other devices which use a BigEndian length variable at the front of the packet.
UseWholePacket
Long
Set this to netWPP:none to disable all WholePacket functionality. Set it to netWPP:LengthPrefix (the default value) to prepend outgoing packets with a simple, 4 byte, length header.
WholePacket
StringTheory
A StringTheory object that contains the whole packet that has been received in the PacketReceived method. To read the text contents of the incoming data use self.WholePacket.GetValue(). To get the length of the data use self.WholePacket.Length().

Methods

MethodDescription
PacketReceivedA whole packet has been received and is now ready for processing.

PacketReceived

PacketReceived ()

Description

This method is called when a whole packet is received by the server or the client.

Notes

This is where most of your embed code will go, handling the results of the requests you have made. The incoming text is in the WholePacket property. This property is a StringTheory object so all the StringTheory methods are available to you here.

The data in the property does not include the header field. It has been removed by this point.

The length of the data can be accessed by using self.WholePacket.Length()
The contents of the data can be accessed by using self.WholePacket.GetValue()

Return Value

The method returns nothing.

See Also

WholePackets

[End of this document]
Return to NetTalk Documentation Index