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;
Property | Description |
BinData | A string (max size 16K) which contains
either text or binary data |
BinDataLen | The 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. |
PacketType | Receiving only. One of
NET:SimpleNewConnection,
NET:SimpleIdleConnection,
NET:SimplePartialDataPacket,
NET:SimpleWholeDataPacket (only when Whole Packet
Protocol is on.) |
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.
_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
Property | Description |
Error | Contains the Error number of the last error,
cleared when next big method is called |
ErrorString | Contains the Error String of the last
error |
LoggingOn | Set in the constructor if logging is on |
LoggingErrorsOnly | Set in the constructor if errors
logging (only) is on |
SSLError | Used when self.Error =
ERROR:ErrorStoredInSSLError |
UseThisThread | Allows 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
Method | Description |
CreateFolder | Creates a folder by iterating down the
folder creating each step along the way. Supports both
c:\ and \\
naming schemes. |
GetElapsedTimeUTC | Returns 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. |
InterpretError | Provides a text interpretation of the
error number. |
Log | Sends a string to DebugView if LoggingOn is true
(or LoggingErrorsOnly is true and this is an error.) |
Start | Return the object to a virgin state as if it
had just been created. |
Trace | Send 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
Parameter | Description |
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
Parameter | Description |
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
Property | Description |
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 long | This 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
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
Parameter | Description |
MessageID | The 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
Properties
Property | Description |
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
Method | Description |
PacketReceived | A 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