|
NetSimple Objects and Direct Port Communications |
|||
![]() |
|||
| Version www.capesoft.com Updated 20 February 2008 |
|||
|
Learn
NetTalk
|
Examples
|
Common
Features |
NetAuto
Objects |
NetSimple
Objects |
Dial-Up
|
Support
|
Version
History
|

This document
covers the NetSimple object.
This object allows you to establish a
TCP/IP or UDP/IP connection directly to a port on another
machine
or to create a NetSimple server to listen on a
port for incoming connections.
The NetSimple object allows you to establish a TCP/IP or UDP/IP connection directly to a port on another machine or to create a NetSimple server to listen on a port for incoming connections.While you will find that the NetAuto objects (NetServer and NetClient) provide you with the functionality for creating your own programs that can communicate with one another, you may want to interface with other processes that do not use NetAuto. Or you may prefer to use NetSimple because it works easier through a proxy / firewall.
For example you may want to access a Mail server, a FTP server, a Web server, or you may want your application to talk to a Java or a C application. In these cases you will need to use the NetSimple objects.
This object allows you to create either:
1. a Listening Port (a NetSimple Server)
2. a Client Connection to a listening port. (a NetSimple Client)
For instance, if you wanted to connect to a server you would use the NetSimple object as a client. More on this in the How to use NetSimple as a Client or a Server section.
We have also built other objects based on the NetSimple object for:
- Sending and receiving Email & News. (NetEmailSend, NetEmailReceive, NetNewsSend & NetNewsReceive objects).
- Connecting to a Web server. (NetWebClient object).
- Transferring files to and from an FTP server. (NetFTPClientControl & NetFTPClientData objects and the FTP Control Template).
- SNMP - (SNMP)
NetSimple gives you the option to use TCP or UDP to send / receive data.
TCP vs UDP
Most people will want to use TCP (transfer control protocol), which is the NetSimple's default. TCP is used for Email, Web, FTP and in fact most other applications.
Here's some of the differences between TCP and UDP:
Our advice for choosing between TCP or UDP:
TCP provides a one-to-one, connection-oriented, reliable communication service. TCP is responsible for the establishment of the connection, the sequencing and acknowledgment of packets sent, and some recovery of packets lost during transmission.
UDP provides a one-to-one or one-to-many, connectionless, unreliable communication service. UDP is used when the amount of data to be transferred is small (such as the data that would fit into a single packet), when the overhead of establishing a TCP connection is not desired, or when the applications or upper layer protocols provide reliable delivery.
Unlike TCP, the User Datagram Protocol (UDP) does not present data as a stream of bytes, nor does it require that you establish a connection with another program in order to exchange information. Data is exchanged in discrete units called datagrams, which are similar to IP datagrams. In fact, the only features that UDP offers over raw IP datagrams are port numbers and an optional checksum. UDP is sometimes referred to as an unreliable protocol because when a program sends a UDP datagram over the network, there is no way for it to know that it actually arrived at it’s destination. This means that the sender and receiver must typically implement their own application protocol on top of UDP. Much of the work that TCP does transparently (such as generating checksums, acknowledging the receipt of packets, retransmitting lost packets and so on) must be performed by the application itself.
With the limitations of UDP, you might wonder why it’s used at all. UDP has the advantage over TCP in two critical areas: speed and packet overhead. Because TCP is a reliable protocol, it goes through great lengths to insure that data arrives at it’s destination intact, and as a result it exchanges a fairly high number of packets over the network. UDP doesn’t have this overhead, and is considerably faster than TCP. In those situations where speed is paramount, or the number of packets sent over the network must be kept to a minimum, UDP is the solution.
Use TCP (default) unless you have to talk to some other application that only can communicate using UDP.
To use UDP in NetSimple:
1) Turn on the UDP tick box in the Procedure Extensions (in the Settings Tab).
2) Most of the properties & methods are fairly similar, but check the info in these sections. (You now need to specify a UDPToPort before calling the send() method, and you can also see a UDPFromPort when you receive data.
3) It is not advisable to send more that 512 bytes in one packet. This is what Microsoft recommends, "It is generally inadvisable for a broadcast datagram to exceed the size at which fragmentation can occur, which implies that the data portion of the datagram (excluding headers) should not exceed 512 bytes.".
More information about UDP:
http://www.capesoft.com/Cached/UDP.htmTip: For the best explanation of a step-by-step guide on how to use NetSimple please see the NetSimple.Open Method in the NetSimple Method section.
This object is demonstrated in the NetDemo example (as well as in the other NetSimple examples).
To use this object you need to do the following: (You will find this section easier to understand if you have already worked through scenario one).
1) Open or create a new application in Clarion.\2) Clarion 5 Users (only):
2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" Button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Use the NetTalk extension template to create your own object based on the NetSimple class. You could call your object anything you like (e.g. "ourClient" or "ourServer"). In the Settings tab you now need to choose whether this NetSimple object will behave like a client or like a server. Choose either Client or Server.
5) You now need to override whichever methods you need to use. See the NetSimple Methods section. You can send and receive data in the object's property which are described in the NetSimple Properties section.
Tip: For the best explanation of a step-by-step guide on how to use NetSimple please see the NetSimple.Open Method in the NetSimple Method section.To see this all in action look at the NetDemo example application.
More details to follow, but the completed code example of this Jump Start can be found in the examples that ship with NetTalk.
Tip: For the best explanation of a step-by-step guide on how to use NetSimple please see the NetSimple.Open Method in the NetSimple Method section.
Note: When you see (Notification Method) it means that the method is called (or fired) when something happens. e.g. The ConnectionClosed() method is called when the connection is closed by the remote machine. This allows you to populate these methods with code, so that your program can respond correctly when connections close, or data arrives etc.
Abort()
This aborts the client connection or server listening port, and discards any data (either incoming or outgoing) that the DLL has. This can be used in situations where you want the connection aborted immediately. The NetSimple queues data to the DLL, which sends it out as fast as possible. This method() gives you the chance to get rid of data you sent to the DLL, but which has not gone across the network yet.
(Not meaningful in UDP mode)In many cases you will rather want to use the Close() method, as it waits until all your queued up data has been sent.
Important Distinction between Abort() and Close()|
Abort(): Closes the connection immediately, and discards any unsent data (sitting in the NetTalk DLL).
Close(): Waits until any unsent data (waiting in the DLL) has been sent, and then gracefully closes the connection.Note: It's often best to check if the connection is open, before trying to abort it, otherwise Abort() will call .ErrorTrap - (particularly if you are calling .Abort() in .ErrorTrap - otherwise you'll recursively call .ErrorTrap(), which is a bad thing). So the following code is recommended:
if (self.OpenFlag or |
self.AsyncOpenBusy)
! Okay we know the connection is
! either open or busy opening
self.abort() ! immediately abort
end
Tip: This is the only method that can close a connection that is busy opening in asynchronous mode.
AbortServerConnection (ulong p_Socket, long p_SockID)
Only meaningful with NetSimple in Server mode.
This aborts the server connection rather than gracefully closing it. See also CloseServerConnection() and see Abort() for a distinction between Abort() and Close().
Important: It is better to use the CloseServerConnection() method to close a server connection. Only use AbortServerConnection() when CloseServerConnection() is not going to be fast enough for you.
Close()
Shuts down the connection or listening port that you setup when you called the Open() method.
This method performs a graceful close. i.e. Data that has been sent from the object to the NetTalk DLL will be sent, and the NetTalk DLL will send the object data already received that was waiting in the NetTalk DLL. No new data will be received and the socket will be closed properly once all data has been sent.
(Not meaningful in UDP mode)
Note: If the object's window is closed before the Close() method is called, any incoming data in the NetTalk DLL will not get to the object as the object is closed when the window closes. NetTalk does not guarantee that data waiting in the NetTalk DLL will be sent, after the object is killed and taken out of scope (e.g. the window closed). This means that when using the Email and News objects you still need to keep the windows open until the MessageSent() or the ErrorTrap() methods have been called. i.e. A command is sent and a reply is given before the next command is sent. So closing the window before the mail has finished being sent may not guarantee that the mail will be sent.
CloseServerConnection(ulong p_Socket, long p_SockID)
This method closes a connection that is connected to the listening port that you created using a NetSimple object in Server mode.
See also AbortServerConnection().
ConnectionClosed(), Virtual
(Notification Method)
Client Use:
Called when your connection was closed by the remote server.
Server Use:
Called when a client that was connecting to your server disconnects. To find out which socket and SockID where just closed look in the self.packet.Socket and self.packet.SockID properties.
(Not meaningful in UDP mode)
ErrorTrap(string errorStr, string functionName) ,Virtual
(Notification Method)
This method is called when an error occurs. Typically you will want to override this method and place in your code to handle errors when they occur.
Often you'll want to suppress messages from being displayed in this function. You can do this by setting the Suppress Error Messages checkbox in the extension template.
GetInfo (long Options=1)
Reports the number of packets in the NetTalk DLL that have been sent from the NetSimple object, but not yet sent down the network connection from the NetTalk DLL. This value is set in self.OutgoingDLLPackets
If Options = 2 it also sets the value of self.OutgoingDLLPacketsBytes, which is the number of bytes in these packets.
Init(uLong Mode=NET:SimpleClient)
Initialises the object. Automatically called from the NetTalk template.
InterpretError(), String
Converts the self.Error property to a text string (returned).
Kill()
Kills the object (opposite of Init). Automatically called from the NetTalk template.
Open (string Server, uShort Port=0)
Client Use: This method establishes a connection to the Server and Port number specified in the parameters.
For complete example code please look at the examples or the NetSimple JumpStart.
By default self.AsyncOpenUse is set to on (1) in the .Init() method, so this function opens the connection asynchronously.Asynchronous Behavior
This is the default behavior of the NetSimple Objects. Asynchronous means that the function is performed behind the scenes. In other words, when you call the Open() method it returns before the connection has been opened, and the act of opening the connection is done in the background. If the connection opens correctly the .Process() method is called with a packet type of Net:SimpleAsyncOpenSuccessful or if the connection fails to open the .ErrorTrap is called with a packet type of Net:SimpleAsyncOpenFailed.Synchronous Behavior
If you set self.AsyncOpenUse = 0, the Open() method will behave synchronously. This means when the function returns you know it either worked or didn't. From this point of view it's quite nice. However if the connection fails you can end up waiting 45 to 90 seconds before WinSock decides that the connection has in fact not worked. This is undesirable as your window will appear to lock up for this length of time.
The best solution: Use the default Asynchronous Behavior.
Asynchronous Open
MyC.AsyncOpenUse = 1
MyC.AsyncOpenTimeOut = 1200 !12sec
MyC.InActiveTimeout = 9000 !90sec
MyC.Open (clip(Server), Port)
! Note that the connection is now
! open asynchronously
! once it is opened .Process()
! will be called
This approach means that your call to .Open() returns immediately and the process of trying to connect to the server is done in the background. During which your program keeps responding to users, re-drawing the screen, or doing other processing. Another advantage of asynchronous open over synchronous open is that you can specify the amount of time after which to give up. And with most sites, if you haven't connected to them in 9 seconds, you probably won't connected to them even if given more time.
To use asynchronous open you need to:
1) Set .AsyncOpenUse = 1
Example:
MyC.AsyncOpenUse = 1
2a) You may also want to change the value of the timeouts. There are two timeouts:
AsyncOpenTimeout: The length of time (in hs) after which to stop trying to establish the connection).
InActiveTimout: The length of time, (after the connection is esablished) to report InActivity (Idle connection) on the connection.
Example:
MyC.AsyncOpenUse = 1
MyC.AsyncOpenTimeout = 1200 ! 12 sec
MyC.InActiveTimeout = 9000 ! 90 sec
MyC.Open ('MachineName', 80)
2b) To use NetSimple in SSL (Secure Sockets Layer) you should use the following code:
MyC.AsyncOpenUse = 1
MyC.AsyncOpenTimeout = 1200 ! 12 sec
MyC.InActiveTimeout = 9000 ! 90 sec
MyC.SSL = 1
MyC.SSLCertificateOptions.CertificateFile = |
CertificateFile
MyC.SSLCertificateOptions.PrivateKeyFile = |
PrivateKeyFile
MyC.SSLCertificateOptions.DontVerifyRemoteCertificateWithCARoot=|
DontVerifyRemoteCertificateWithCARoot
MyC.SSLCertificateOptions.DontVerifyRemoteCertificateCommonName=|
DontVerifyRemoteCertificateCommonName
MyC.SSLCertificateOptions.CARootFile = |
CARootFile ! Or '' for none
MyC.Open ('MachineName', 80)
Note: Please take note of the files you need to distribute (in the Distribution section of the main NetTalk document) if you are using SSL.
(see FAQ G8 and also the NetWebSecure section of the docs.)
3) Because this is asynchronous, the call to .Open() will return before we know whether the connection has worked or failed. To find this out you'll need to put code into two places:
3a) If the connection fails, the ErrorTrap() method will be called. So in .ErrorTrap() you could put something like this:
if self.Packet.PacketType = |
NET:SimpleAsyncOpenFailed
Message ('Connection failed to'&|
' open.' & |
' NetError = ' & |
self.packet.NetError & |
' SSLError = ' & |
self.packet.SSLError & |
' WinSockError = ' & |
self.packet.WinSockError)
end
3b) If the connect establishes the .Process() method is called. You can place code into .Process() like this:
case self.Packet.PacketType
of NET:SimpleAsyncOpenSuccessful
! Our asynchronous open worked
! You might want to send data here
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimplePartialDataPacket
! Was the same as Net:SimpleDataPacket
! We received a partial packet
ReceivedData = |
self.packet.binData[1:|
self.packet.binDataLen]
! You might want to send data back
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimpleWholeDataPacket
! If you set
! self.WholePacketUseLengthField
! and you are talking to your own
! client and server,
! then you can get these
! whole packets.
! We received a whole packet
ReceivedData = |
self.WholePacketQueue.WholeBinData [1: self.WholePacketQueue.WholeBinDataLen]
! You might want to send data back
self.WholePacketSend(MyData, MyDataLen)
of NET:SimpleIdleConnection
! Connection has been
! idle for period set
! in .InactiveTimeout
self.abort()
Message ('Our Connection was idle')
end
4) If you used the .OpenFlag property to determine if a connection was open you may need to also check the .AsynOpenBusy property, which tells if a connection is busy opening asynchronously. For example:
if (self.OpenFlag or self.AsyncOpenBusy)
! Okay we know the connection is
! either open or busy opening
self.abort() ! immediately close
end
Tip: The only method that can close a connection that is busy being opened asynchronously is self.abort()
Server & UDP Use:
This method sets up a listening server Port on the specified Port parameters.
1a) If you leave the Server string set to '' (default behaviour) then the listening port will listen on all the IP addresses on that computer.
Example:
MyServer.Open ('', 80) ! Listen on all IPs
1b) If your machine has more than one IP address or you would rather bind to 127.0.0.1 (which will only be available from the local machine), then set the Server string set to the desired IP address. (Please note if the machines TCP/IP protocol (Control Panel - Networks) has not been configured to support the IP you specify, NetSimple will default to using all available IP addresses).
Example:
MyServer.Open ('127.0.0.1', 80)
or
MyServer.Open ('192.168.2.1', 80)
1c) To run your Server as a SSL use the following code:
MyS.SSL = 1
MyS.SSLCertificateOptions.CertificateFile = |
CertificateFile ! Or '' for none
MyS.SSLCertificateOptions.PrivateKeyFile = |
PrivateKeyFile ! Or '' for none
MyS.SSLCertificateOptions.DontVerifyRemoteCertificateWithCARoot=|
DontVerifyRemoteCertificateWithCARoot
! Next line Must be set to 1
! For a NetSimple Server !!
MyS.SSLCertificateOptions.DontVerifyRemoteCertificateCommonName=1
MyS.SSLCertificateOptions.CARootFile = |
CARootFile ! Or '' for none
PartiallyCloseServer()
This method closes just the Server Listening port, while leaving any server connection active.
Ping (string p_IP, long p_TTL),long
This method allows you to ping an IP address or a Host Name. This is an synchronous function. i.e. It only returns when the ping command and echo have been received.
TTL = microseconds (i.e. 1000 = 1 second)
Example:
result = ThisPing.Ping ('127.0.0.1', 3000)
case (result)
of 0
Message ('Ping sucessful')
of ERROR:AddressNotFound
Message ('Invalid address')
of ERROR:CouldNotLoadProcedures
Message ('The PING code is unsupported ' &|
'on this computer')
else
Message ('Ping Failed!')
end
Please bear in mind:
1) That when you call the ping command with a hostname like 'www.winzip.com' that a DNS call will need to be made first to convert the hostname to an IP address.
2) Ping will not work through some proxy servers.
3) If the host you are pinging is running a firewall (incuding Windows Firewall), they may have blocked the Ping command, so the ping may fail even if the host is alive.
Process(), Virtual
(Notification Method)
This method is called whenever a packet is received by the object. You need to override this method (using the Advanced tab of the extension template or by typing code into the source of your procedure). The data received is found in the packet property. See the NetSimple Properties section for more info.
Tip: Read up on self.packet.packetType. This method is well demonstrated in the netdemo example application.
Example Client Use:
(If you are using asynchronous open then once your connection is established .Process() will be called with self.packet.packetType = NET:SimpleAsyncOpenSuccessful)
case self.Packet.PacketType
of NET:SimpleAsyncOpenSuccessful
! Our asynchronous open worked
! You might want to send data here
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimplePartialDataPacket
! Was the same as Net:SimpleDataPacket
! We received a partial packet
ReceivedData = |
self.packet.binData[1:|
self.packet.binDataLen]
! You might want to send data back
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimpleWholeDataPacket
! If you set self.WholePacketUseLengthField
! and you are talking to your own client
! and server, then you can get these
! whole packets.
! We received a whole packet
ReceivedData = |
self.WholePacketQueue.WholeBinData[1:|
self.WholePacketQueue.WholeBinDataLen]
! You might want to send data back
self.WholePacketSend(MyData, MyDataLen)
of NET:SimpleIdleConnection
! Connection has been
! idle for period set
! in .InactiveTimeout
self.abort()
Message ('Our Connection was idle')
end
Example Server Use:
(This method is also called when a new server connects. In this case the self.packet.packetType is set to NET:SimpleNewConnection.)
case self.Packet.PacketType
of NET:SimpleNewConnection
! A new connection to our Server
! You may want to send data now
self.packet.ToIP = self.packet.FromIP
! self.packet.SockID is same as sender
! self.packet.Socket is same as sender
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimplePartialDataPacket
! Was the same as Net:SimpleDataPacket
! We received a partial packet
ReceivedData = |
self.packet.binData[1:|
self.packet.binDataLen]
! You might want to send data back
self.packet.ToIP = self.packet.FromIP
! self.packet.SockID is same as sender
! self.packet.Socket is same as sender
self.packet.binData = MyData
self.packet.binDatalen = |
len(clip(self.packet.binData))
self.send()
of NET:SimpleWholeDataPacket
! If you set self.WholePacketUseLengthField
! and you are talking to your own client
! and server, then you can get these
! whole packets.
! We received a whole packet
ReceivedData = |
self.WholePacketQueue.WholeBinData[1:|
self.WholePacketQueue.WholeBinDataLen]
! You might want to send data back
self.packet.ToIP = self.packet.FromIP
! self.packet.SockID is same as sender
! self.packet.Socket is same as sender
self.WholePacketSend(MyData, MyDataLen)
of NET:SimpleIdleConnection
! Connection has been
! idle for period set
! in .InactiveTimeout
self.abortserverconnection(|
self.packet.OnSocket, |
self.packet.SockID)
end
RefreshQServerConnections(long p_Free)
Force refreshes the Server Connections Queue.
Send(), Virtual
See also WholePacketSend()
Client Use:
This method is used to send a packet to the port that you connected to. You simply need to set the
self.packet.binData and
self.packet.binDataLen
properties, before calling self.send().
Server Use:
This method is used for sending data to one of the clients that are connected to your listening port.
You need to set the
self.packet.ToIP
self.packet.OnSocket
self.packet.SockID
self.packet.binData and
self.packet.binDataLen
properties before sending data. Look at the breakdown for Net:SimplePacketType.
UDP Use:
This method is used for sending a UDP packet from your machine to another host/port. If you have opened a listening port then the UDP packet will be sent from that port, otherwise a tempory socket/port is created, the data sent and the socket/port closed.
You need to set the
self.packet.ToIP
self.packet.UDPToPort
self.packet.binData and
self.packet.binDataLen
properties before sending data.
Important Note and Code Sample:
See the .DontErrorTrapInSendIfConnectionClosed property for how to avoid -34 errors.
Important Note:
This function is performed asynchronously. i.e. When you call this function your packet is sent to the DLL to send down the socket when the socket can next accept data, this normally happens very fast (like most Winsock applications), but this function does not guarantee that your packet has reached its destination by the time it returns. Any errors that are encountered will result in .ErrorTrap() being called. And when new data arrives .Process() will be called.
SSLGetIssuerField(string p_FieldName),String
Returns the value of the Issuer part of the Remote Certificate.
For example:
! Return Issuer Common Name
self.SSLGetIssuerField('CN')
SSLGetSubjectField(string p_FieldName),String
Returns the value of the Issuer part of the Remote Certificate.
For example:
! Return Subject Common Name
self.SSLGetSubjectField('CN')
TakeEvent()
Processes events from the NetTalk DLL. Called automatically by the NetTalk template.
WholePacketCheckForWhole()
Advanced Users:
This method checks the contents of the current record in the WholePacketQueue buffer to see if a whole packet has arrived (e.g. it looks at the length field and then determines if that number of bytes have actually been received).
This method is called automatically if you set self.WholePacketUseLengthField = 1
Demonstrated in the NetSimple Auto Packet Boundaries & Encryption example.
WholePacketFree(long p_SockID)
Advanced Users:
Frees the data used for the p_SockID in the WholePacketQueue.
Called automatically.
Demonstrated in the NetSimple Auto Packet Boundaries & Encryption example.
WholePacketSend(&String, long p_Length)
This method allows you to send data of any size. (As opposed to the Send() method, which limits you to sending 16K at a time). Note: If you have set self.WholePacketUseLengthField = 1, then a length field (4 bytes) will be sent at the front of the packet. This option is very useful when sending data to your own applications, as the WholePacket will be reassembled from all the Partial Packets at the recipients end. This option won't work if the recipient is not one of your own applications as it will not know what to do with the extra 4 bytes for the length field.
Client Use:
This method is used to send a packet to the port that you connected to. You simply need to call:
self.WholePacketSend(string, length)
Server Use:
This method is used for sending data to one of the clients that are connected to your listening port.
You need to set the 3 properties and then call WholePacketSend
self.packet.ToIP
self.packet.OnSocket
self.packet.SockID
self.WholePacketSend(string, length)Important Note:
This function is performed asynchronously. i.e. When you call this function your packet is sent to the DLL to send down the socket when the socket can next accept data, this normally happens very fast (like most Winsock applications), but this function does not guarantee that your packet has reached its destination by the time it returns. Any errors that are encountered will result in .ErrorTrap() being called. And when new data arrives .Process() will be called.
Demonstrated in the NetSimple Auto Packet Boundaries & Encryption example.
WholePacketStorePartialPacket()
Advanced Users:
This method appends the partial packets to the .WholePacketQueue.This method is automatically called if you set self.WholePacketUseLengthField = 1
Advanced Users:
You could also call it manually to add data to the WholePacketQueue
If you are using self.WholePacketUseLengthField = 0, and are calling self.WholePacketStorePartialPacket yourself, then the data you have received so far, is available via
self.WholePacketQueue.WholeBinData
[1:self.WholePacketQueue.BufferUsed]
Demonstrated in the NetSimple Auto Packet Boundaries & Encryption example.
WholePacketTruncate(long p_Bytes)
Advanced Users:
This method truncates p_Bytes off the current item in the WholePacketQueue queue buffer.
If the BufferUsed is then zero the string is disposed., unless self._WholePacketDontFreeWholeBinData is set to 1
Demonstrated in the NetSimple Auto Packet Boundaries & Encryption example.
AsyncOpenBusy long Read-only. Indicates if a connection is busy opening using asynchronous open. Read more in NetSimple.Open
AsyncOpenUse long Set this property to 1 to use Asynchronous Open. Read more in NetSimple.Open
By default this is set to 1 (on).
AsyncOpenTimeOut long This is length of time in hs (hundreths of a second) after which the asynchronous open will timeout. Defaults to 9 seconds (900hs). Example use:
self.AsyncOpenTimeout = 200 ! 2 seconds
or
self.AsyncOpenTimeout = 1000 ! 10 seconds
Read more in NetSimple.Open
Tip: Although this property is measured in hs it will only timeout to an accuracy of a second.
_Connection Group(Net:SimpleConnectionType)
This group holds the connection details. You may want to specify the self._connection.MaxServerConnections which allows you to limit how many incoming connections a server can handle. The default is 0 = unlimited.
We've marked this as an internal property (all properties and methods that are prefixed with a "_" are internal), but you may want to read some properties out of this Group.
See the breakdown for Net:SimpleConnectionType.
DontErrorTrapInSendIfConnectionClosed Long Because of the 3 levels of architecture in NetTalk, namely WinSock, the NetTalk DLL and the NetTalk objects. Under some circumstances it is possible that your object tries to send data down a connection that has actually closed, but the object is not aware of this yet. WinSock and the NetTalk DLL are aware of this, but not the object. This situation often occurs when accessing a web server. Once your page has downloaded your application tries to fetch another page, using the same connection. Unbeknown to the object the web server closes it's connection. Previously this would cause a 10038 error, currently this would cause a -34 error. The best way to code around this is now like this:
mC.DontErrorTrapInSendIfConnectionClosed = 1
mC.Send()
if mC.Error = ERROR:ClientNotConnected
! This error occurs if the connection
! closes and we try and send data on it,
! before the object knows the object has
! actually closed.
Message ('The connection has already ' & |
'closed, will try and open ' & |
'the connection again')
! You may want to rather try re-opening
! the connection ....
end
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()
Tip: Although this property is measured in hs it will only timeout to an accuracy of a second.
LogDataBytes long Logs up to this many bytes to DebugView, in the .Send() method, when the application is run with the /nettalklog command line parameter. (Default = 0 = off)
OpenFlag Long
Read-only
Client Use:
When 0 the connection is not established
When 1 the connection is established
Do not change the value of this yourself.
Note: You will probably want to use this property in conjunction with the .AsyncOpenBusy property to determine if a connection is busy opening in asynchronous mode.
Server Use:
When 0 the object is not listening on the port
When 1 the object is listening on the port
Do not change the value of this yourself.
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.
Packet Group(Net:SimplepacketType)
Used for sending and receiving data. This contains all the data for sending and receiving. Look at the breakdown for 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 are to the listening port.
(Not meaningful in UDP mode)
SSL Long
Set this to 1 to use a SSL (Secure Socket Layer) connection. Defaults to 0.
Note: Be sure to read about the SSL DLL Distribution.
Note: This implementation does not do certificate checking yet (we plan to add this later on), but it will allow you to communicate and download from secure sites.
Note: See FAQ G8 - for tips to getting SSL to work.
SSLCertificateOptions group(Net:SimpleSSLCertificateOptionsType).
Options for the SSL Certificates and Certificate Verification.
See Net:SimpleSSLCertificateOptionsType
SSLError long
Contains the SSL Error Code.
See also self.Error and self.WinSockError
SSLMethod Long
Set to one of :
NET:SSLMethodTLSv1
NET:SSLMethodSSLv3
NET:SSLMethodSSLv2
NET:SSLMethodSSLv23
! NET:SSLMethodSSLv3 = Default.
! Tries TLS v1.0, then SSL v3.0,
! then SSL v2.0
SSLDontConnectOnOpen Long
By default (0) the SSL connection will perform the SSL connection on the open.
Set this to 1 to turn it off (this gives you the option to call self._SSLConnect when you want to switch a connection from non-SSL to SSL).
SuppressErrorMsg Long
Set this to 1 to disable error messages, otherwise leave it as 0.
UseThisThread long (Advanced Optional Property). This property allows you to manually specify which thread must receive the messages that the NetTalk DLL posts to the NetSimple objects. Set this property before calling the Init() method. Defaults to 0 (no action).
WholePacketQueue &Net:SimpleWholePacketQueue
This queue allows you to read incoming whole packets. See Net:SimpleWholePacketQType
Note: If you are using self.WholePacketUseLengthField = 1 then, when Process is called with a packet type of Net:SimpleWholeDataPacket, then the current data is in the queue buffer of this queue, and is accessable via
self.WholePacketQueue.WholeBinData
[1:self.WholePacketQueue.WholeBinDataLen]Note: If you are using self.WholePacketUseLengthField = 0, and are calling self.WholePacketStorePartialPacket yourself, then the data you have received so far, is available via
self.WholePacketQueue.WholeBinData
[1:self.WholePacketQueue.BufferUsed]
WholePacketUseLengthField long
Defaults to 0, But if you set it to 1 the NetSimple object will:
a) Append a length field (4 bytes) to the top of all packets sent via the self.WholePacketSend() method
b) Will manage the incoming partial packets as they arrive and will cache them up until the full length of the whole packet arrives (as specified in the length field). Then self.Process will be called with a packet type of Net:SimpleWholeDataPacket
Note: You can only use this property if you are in control of both the client and the server parts of the connection, as the extra length field will break any protocol that is not expecting this field.
WinSockError long
Contains the WinSock Error Code.
See also self.Error and self.SSLError
Net:SimpleWholePacketQType Queue, Type
SockID long Matching SockID
WholeBinData &string Data Buffer (dynamically allocated)
WholeBinDataLen long Length of packet (if using self.WholePacketUseLengthField)
BufferUsed long Length of Data in the Buffer
_BufferSize long Size of Buffer (not all of it may be used, but it is allocated)
Net:SimplePacketType Group, Type
ToIP cstring (NET:IPStringSize + 1) Client Use:
Not required.
Server Use:
Set this to the client you want to send messages to. Use the values in the FromIP when packets are sent, or you can also use the qServerConnections queue to give you all the details of all the connections to this listening port. See the NetDemo application for an example of this.
OnSocket NET:SocketType (long) Identifies the socket on which the packet was or will be sent. See also .SockID
SockID long Used with Socket to uniquely differentiate the different connections you are using. If you are receiving a packet, then these are the details of the socket that the data arrived on. When you are sending data these are the details of the socket you want to send the data out on.
FromIP cstring (NET:IPStringSize + 1) Client Use:
Not really needed. As all packets come from the server/port that you connected to.
Server Use:
Lets you know who send the packet.
BinData String(NET:MaxBinData) This is the binary data (stored in a string) that you receive and send. NET:MaxBinData = 16384 bytes (16K)
BinDataLen long Specifies the length of data in BinData.
PacketType long Client Use:
NET:SimpleAsyncOpenSuccessful (Connection established asynchronously)
NET:SimpleAsyncOpenFailed (Connection could not be established asynchronously - reported in .ErrorTrap())
NET:SimpleIdleConnection (A new client connected)
NET:SimplePartialDataPacket (Data packet received)
(was Net:SimpleDataPacket)
Server Use:
Either set to
NET:SimpleNewConnection (A new client connected)
NET:SimpleIdleConnection (A new client connected)
NET:SimplePartialDataPacket (Data packet received)
(was Net:SimpleDataPacket)
_DebugPacketNumber long Reserved.
UDPToPort Net:PortType (ushort) UDP Use:
This is the port of the machine you are sending data to.
UDPFromPort Net:PortType (ushort) UDP Use:
This is the port of the machine that sent you the data.
NetError long Internal NetTalk Error Number
WinSockError long Internal WinSock Error Number
SSLError long Internal SSL Error Number
_Reserved string Reserved
Net:SimpleConnectionType Group, Type
Mode long
Read-onlyThis determines whether the connection is running in Client or Server mode. Will either be:
NET:SIMPLE_CLIENT or
NET:SIMPLE_SERVER
Server cstring (NET:StdStringSize)
Read-onlyCan be a text-based hostname or the IP address.
Port NET:PortType (ushort)
Read-onlyIn Client Mode this is the port to connect to.
In Server Mode this is the port to listen on.
Socket NET:SocketType (long)
Read-onlySocket Connection Handle (Defined by Winsock).
SockID long
Read-onlyThe NetSimple Socket ID number.
NotifyThread long
Read-onlyThe thread on which this connection was opened.
NotifyEvent long
Read-onlyAn internal NetTalk Windows Message number.
MaxServerConnections long
Server Mode Only:
Sets the max number of incoming connections that will be allowed to connect to this listening port. This property needs to be set before calling the Open() method.
LocalIP cstring (NET:IPStringSize+1)
Read-onlyThe IP address of the local machine, as seen from the remote machine.
_Internal.IP Net:IPType (long)
Read-onlyReserved. No not change.
UDPmode long UDP Use:
When this long is set to 1 (normally done via the template), then NetSimple object will use the UDP protocol instead of the normal TCP protocol. To change this go to the NetTalk extensions template and to the Settings tab. There you will find an option to run NetSimple in UDP mode.
Make sure you've read the TCP vs UDP section before you use UDP.
AsyncOpenTimeOut long Automatically set from self.AsyncOpenTimeout
Don't change this
SSL long Automatically set from self.SSL
Don't change this
Note: See FAQ G8 - for tips to getting SSL to work.
SSL_Method long Automatically set from self.SSLMethod
Don't change this
SSL_DontConnectOnOpen long Automatically set from self._SSLDontConnectOnOpen
Don't change this
_SSL_CertificateOptionsPointer long Automatically set to point at self.SSLCertificateOptions
Don't change this
This is a queue that stores a list of all connections that are connected to a listening server port.
Net:SimpleServerConnectionsQType Queue, Type
RemoteIP cstring (NET:IPStringSize+1) IP address of the Remote machine
Socket NET:SocketType (long) WinSocket Socket Descriptor Handle
SockID long NetSimple Socket ID number
RemotePort NET:PortType (ushort) Remote Port that connected to this listening server. The word Port is used lightly as it is not a listening Port, but this is the port that the remote machine would list if it did a netstat.
LocalIP cstring (NET:IPStringSize + 1) The local IP address.
Net:SimpleMultiClientQType Queue, Type
_Connection Group(Net:SimpleConnectionType). A connection group of type NET:SimpleConnectionType
Packet Group(Net:SimplePacketType). A packet group of type NET:SimplePacketType
OpenFlag Long Indicates if the connection is open. After calling the close() method the record will remain in the queue while the connection closes, but it it immediately marked as OpenFlag = 0
See also AsyncOpenBusy.
SockID long A unique connection identifier.
_BetweenPhaseOneAnTwo long Reserved. Internal Property. Don't change this.
_IgnorePhaseTwo long Reserved. Internal Property. Don't change this.
AsyncOpenBusy long Indicates if the connection is busy opening asynchronously. See also OpenFlag.
Net:SimpleSSLCertificateOptionsType Group, Type
_Size long Reserved. Do not change this.
_Reserved1 long Reserved. Do not change this.
DontVerifyRemoteCertificateCommonName long Tells this object not to verify that the remote certificate's Common Name matches the Server name of the connection.
NetSimple Servers must set this to 1.
NetSimple Clients can choose (default = 0)
DontVerifyRemoteCertificateWithCARoot long Tells the object not to verify the remote certificate's Issuer against a list of trusted Issuers (stored in what's called a CA Root File).
CARootFile string(260) Path to the CA Root File (see DontVerifyRemoteCertificateWithCARoot)
CertificateFile string(260) Path to the Local Certificate. Typically this is a .crt or .pem file)
PrivateKeyFile string(260) Path to the Local Certificates Private Key File. Typically this is a .key or .pem file.
RemoteCertificateHaveDetails long Set once the RemoteCertificate fields are set (see below).
RemoteCertificateVersion long The Version number of the remote certificate.
RemoteCertificateSubject string(NET:SSLSubjectLen) The remote certificate subject. Use self.SSLGetSubjectField() to get values out of this string.
RemoteCertificateIssuer string(NET:SSLSubjectLen) The remote certificate issuer. Use self.SSLGetIssuerField() to get values out of this string.
RemoteCertificateNotBeforeDate long Not Before Date of the Remote Certificate. Note: No GMT to local time calculation has been made to this value. It's a GMT time.
RemoteCertificateNotBeforeTime long Not Before Time of the Remote Certificate. Note: No GMT to local time calculation has been made to this value. It's a GMT time.
RemoteCertificateNotAfterDate long Not After Date (Expiry Date) of the Remote Certificate. Note: No GMT to local time calculation has been made to this value. It's a GMT time.
RemoteCertificateNotAfterTime long Not After Time (Expiry Time) of the Remote Certificate. Note: No GMT to local time calculation has been made to this value. It's a GMT time.
RemoteCertificatePublicKey string(NET:SSLPublicKeyLen) Public Key of the remote certificate. RemoteCertificateAlgorithm long Algorithm of the remote certificate.
RemoteCertificateSerialNumber long Serial Number of the remote certificate.
Reserved string(300) Reserved. Do not change this.
NetSimpleMultiClient is a NetSimple object that has been built to handle multiple client connections.
Comparison Guide:
NetSimple NetSimpleMultiClient Allows you to create either a client or a server Only allows client mode Server supports one listening port with multiple connections No server support Only allows one client connection Supports multiple client connections Allows Client & Server SSL SSL not supported
Programming the NetSimpleMultiClient is very similar to the NetSimple object. We have included a list of properties and methods to help you familiarise yourself with this object.
Basically the biggest change is that there is now a queue of properties. For each connection there is one record in the queue. Therefore the methods act upon the data currently loaded in the queue. (e.g. If you call the close() method, the connect currently loaded in the queue is closed).
This object is demonstrated in the NetDemo example application.
How to learn to use this object?
The best way to learn how to use this object is to start by using the NetSimple object. From there you can then advance to this object.
Note: When you see (Notification Method) it means that the method is called (or fired) when something happens. e.g. The ConnectionClosed() method is called when the connection is closed by the remote machine. This allows you to populate these methods with code, so that your program can respond correctly when connections close, or data arrives etc.
NetSimpleMultiClient Methods
Abort()
This kills the connection currently loaded in the self.q property. It dumps any data (either incoming or outgoing) that the DLL has. This should only be used if you need a button for "I've just sent the wrong data, try and close down as fast as possible". The NetSimpleMultiClient queues data to the DLL, which sends it out as fast as possible. This method gives you the chance to get rid of data you sent to the DLL, but which has not gone down the network yet.
Important: It is better to use the Close() method to close the connection. Only use Abort() when close() is not going to be fast enough for you.
Close()
Shuts down the connection currently loaded in self.q
This method perform a graceful close. i.e. Data that has been sent from the object to the DLL will be sent, and the DLL will send the object data already received that was waiting in the DLL. No new data will be received and the socket will be closed properly once all data has been sent.
Note: If the object's window is closed before the Close() method is called, any incoming data in the NetTalk DLL will not get to the object as the object is closed when the window closes. NetTalk does not guarantee that data waiting in the NetTalk DLL will be sent, after the object is closed down (e.g. the window closed).
CloseAll()
Performs a close() on each connection in self.q
ConnectionClosed(), Virtual
(Notification Method)
Client Use:
Called when your connection was closed by the server. The connection which was closed will be loaded in the self.q property.
ErrorTrap(string errorStr, string functionName) ,Virtual
(Notification Method)
This method is called when an error occurs. Typically you will want to override this method and place in your code to handle errors when they occur.
Typically you'll want to suppress messages from being displayed in this function. You can do this by ticking the Suppress Error Messages in the extension template.
GetInfo()
Reports the number of packets in the NetTalk DLL that have been sent from the NetSimple object, but not yet sent down the network connection from the NetTalk DLL. This value is set in self.OutgoingDLLPackets
If Options = 2 it also sets the value of self.OutgoingDLLPacketsBytes, which is the number of bytes in these packets.
Open (string Server, uShort Port=0)
Client Use:
This method establishes a connection to the Server and Port number specified in the parameters. When the connection is opened a new record will be added in the self.q queue. To test whether this connection is successfully opened test the self.error property.
Important Note:
By default this function is performed synchronously. i.e. When you call this function it will wait while it makes the connection. Once this function has returned the connection has either been established, or an error will have occurred.
To use asynchronous open please refer to the tips and info displayed at the NetSimple.Open() method. (Note that the .AsyncOpenBusy flag is stored in the Q queue of the NetSimpleMulticlient object)
Process(), Virtual
(Notification Method)
This method is called whenever a packet is received by the object. You need to override this method. The data received is found in the packet property. See the NetSimpleMultiClient Properties section for more info.
The connection which received the data will be loaded in the self.q queue.
See also the NetSimple.Process method.
Send(), Virtual
This method is used to send the self.q.packet down it's connection. To send data you must do the following:
1) Make sure the connection you want to send it down is loaded in self.q
2) Set self.packet.BinData
3) Set self.packet.BinDataLen
4) Call the self.send(), or the parent.send()
Important Note:
This function is performed asynchronously. i.e. When you call this function your packet is sent to the DLL to send down the socket when the socket can next accept data, this normally happens very fast (like most Winsock applications), but this function does not guarantee that your packet has reached its destination by the time it returns.
NetSimpleMultiClient Properties
AsyncOpenUse long Set this property to 1 to use Asynchronous Open. Read more in NetSimple.Open
AsyncOpenTimeOut long This is length of time in hs (hundreths of a second) after which the asynchronous open will timeout. Defaults to 9 seconds (900hs). Example use:
self.AsyncOpenTimeout = 200 ! 2 seconds
or
self.AsyncOpenTimeout = 1000 ! 10 seconds
Read more in NetSimple.Open
Tip: Although this property is measured in hs it will only timeout to an accuracy of a second. If this really doesn't suit your program please let us know at support@capesoft.com
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.
ErrorString String(256) Contains the last error string that was reported. It only changes the next time an error occurs.
Q Queue(NET:SimpleMultiClientQType) The contents of the NET:SimpleMultiClientQType Type are described below.
_Connection Group(Net:SimpleConnectionType)
This group holds the connection details. You may want to specify the self._connection.MaxServerConnections which allows you to limit how many incoming connections a server can handle. The default is 0 = unlimited.
We've marked this as an internal property (all properties and methods that are prefixed with a "_" are internal, but you may want to read some properties out of this Group.
See the breakdown for Net:SimpleConnectionType.
Packet Group(Net:SimplepacketType)
Used for sending and receiving data. This contains all the data for sending and receiving. Look at the breakdown for Net:SimplePacketType.
OpenFlag Long
If set to 0 the connection is not established
If set to 1 the connection is established
Do not change the value of this yourself.
SockID long
A unique connection identifier. This is the same as the _Connection.SockID, but having it as a separate property in the queue makes it easier to use.
AsyncOpenBusy long
Read-only. Indicates if a connection is busy opening using asynchronous open. Read more in NetSimple.Open
UseThisThread long (Advanced Optional Property). This property allows you to manually specify which thread must receive the messages that the NetTalk DLL posts to the NetSimple objects. Set this property before calling the Open() method. Defaults to 0 (no action).
These objects are demonstrated in the NetDemo example.
We have provided a Send Email Control template as well as two objects (NetEmailSend and NetEmailReceive) which allow you to add full email functionality into your application.
To use these objects you need to do the following: (You will find this section easier to understand if you have already worked through scenario one).
1. Add the NetTalk Global Template and all the usual basics (see steps 1 to 5 of Scenario One) for each application that will use NetTalk.
2. Use the NetTalk extension template to create your own object based on the NetEmailSend or NetEmailReceive class. You could call your object anything you like (e.g. "ourEmailSend" or "ourEmailReceive").
3. You now need to override whichever methods you need to use. See the NetEmailSend Methods and Properties or the NetEmailReceive Methods and Properties section.
You will prime some of the properties (like the SMTP Server address, and the contents of your email) then you will call the SendMail() method. This puts your email in an outgoing queue. When your email is successfully sent to the SMTP Server the MessageSent() method is called. You can override this method to find out when your emails are sent. If errors occur the ErrorTrap() method is called.
NetEMailSend - what you need to do
You will prime some of properties (like the SMTP Server address, Login and Password) then you will call the Ask() method. This goes and gets the emails from the server. Every time an email arrives the Done() method is fired. You can also use the NetEmailReceive object to count the number of emails, as well as downloading headers before you download the whole email to determine if you want to download it.
NetEmailReceive - what you need to do
4. To see this all in action look at the NetDemo example application.
Note: If the object's window is closed before the Close() method is called, any incoming data in the NetTalk DLL will not get to the object as the object is closed when the window closes. NetTalk does not guarantee that data waiting in the NetTalk DLL will be sent, after the object is closed down (e.g. the window closed). This means that when using the Email and News objects you still need to keep the windows open until the MessageSent() or the ErrorTrap() methods have been called. This is because of the mail protocol behaves in a synchronous fashion. i.e. a command is sent and a reply is given before the next command is sent. So closing the window before the mail has finished being sent may not guarantee that the mail will be sent.
We added a control template to speed up the process of adding email sending functionality to your applications. Using email is now even easier than ever.
There is an example of these controls in action in the NetDemo example application.
1) Open or create a new application.
How to add Send Email Controls to your application:
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Go to the Window formatter of the window procedure that you want the Send Email controls in.
4) Go to the "Populate" Menu and choose "Control Template...".
5) Choose "SendEmailControls" in the Select Control Template Window under "Class NetTalk" and press Select
6) Resize your window so that you can see all the controls. Return to the Application Tree.
7) Right click on the procedure with the Send Email controls and click and choose extensions.
8) In the NetTalk extensions setting you will see three tabs. Click on the "Settings" tab and you will see the options for this extension. You can choose to change these options to suit your program needs.
9) Save your work and Compile and Run your application.
You need to specify your SMTP Server. This is typically something like smtp.yourISP.com and the port is normally 25.
Extra Information
You can use the Send Email control template to send a list of files. Files must either be comma separated or in the format returned from the File Lookup Browse box.
When you go to the "Settings" extension Tab you can tell the Send Email Control Template which variables contain the data you want to use to send email. To start with we have just specified some variables and have displayed th
Optional Extra Settings: