ITK Programmer's Guide


 

Table of contents | Intro | General | TCP Low Level | TCP High Level | UDP | DNS | PPP
Encoding/Decoding | Internet Config | Goodies | Cryptography & SSL | Appendix

 

Chapter 3 : Low-level TCP/IP routines

   

   

Chapter contents:


About this chapter...

This chapter describes the basic TCP/IP routines provided by ITK.

These routines allow to open connections (streams) between two computers using the TCP/IP protocol to transfer data reliably.

   

   


ITK_TCPOpen

Syntax:

streamRef := ITK_TCPOpen (hostName;remotePort;rcvBuffer;tcpOpt;oldStream;localPort;localIP)


Warning:

All streams opened using ITK_TCPOpen MUST be released using ITK_TCPRelease .


Description:

Opens a TCP stream asynchronously (returns control immediately without waiting for the connection to be established with the remote host).
Use ITK_TCPStatus or ITK_TCPWaitConn to wait for the connection to be established.

Use tcpOpt to open an SSL "client" stream instead of a plain TCP stream (added in ITKv2.5). This option is only available in the "Pro" version of ITK.

If remotePort is equal to 443 (HTTPS standard port number), ITK will switch automatically to SSL.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

hostName

 

String

 

TCP address of remote host

"www.internet-toolkit.com" or "194.2.244.11"
See Note#1

->

remotePort

Integer

TCP remote port

ex: 80 for HTTP, 25 for SMTP. See RFC#1700 for assigned numbers.

->

rcvBuffer

Longint

Buffer size for this stream (in bytes)

This parameter is used only under MacTCP.
Accepts values between 8192 and 32767.
Pass 0 for ITK to use a default buffer of 8KB (8192 bytes).

->

tcpOpt

Longint

TCP options (type of service field, leave 0 as default)

This parameter is used only under MacTCP.
See MacTCP Programmer's Manual for more details on the "type of service" values.

option 1024 indicates that an SSL "client" stream should be opened instead of a classical TCP stream (added in ITKv2.5)

->

oldStream

Longint

old stream reference number to reuse (set to 0 to allocate a new stream)

This parameter is obsolete and shouldn't be used anymore.

->

localPort

Integer

local port number

Pass 0 for ITK to choose a local port number.

->

localIP

Longint

local IP address
This parameter is provided for multihoming support.

   

 

<-

streamRef

Longint

stream reference number

Will return 0 if the stream couldn't be created.

Note#1: if you add a "." at the beginning of the TCP address of the remote host (ex: ".www.internet-toolkit.com"), ITK will choose randomly one of the resolved addresses returned by the DNS to do DNS load balancing (see ITK_Name2Addr for more information).


Example:

` open a stream with an HTTP server
$stream := ITK_TCPOpen("www.internet-toolkit.com";80)
If ($stream#0)
  ...
  $err := ITK_TCPRelease($stream)
End If
         
` open an SSL stream with an HTTPS server
$stream := ITK_TCPOpen("www.internet-toolkit.com";443;0;1024) ` SSL stream
If ($stream#0)
  ...
  $err := ITK_TCPRelease($stream)
End If
Back to top


ITK_TCPListen

Syntax:

streamRef := ITK_TCPListen (hostFilter; portFilter; localPort; rcvBuffer; tcpOpt; oldStream; localIP)


Warning:

All streams opened using ITK_TCPListen MUST be released using ITK_TCPRelease .


Description:

Opens a "passive" or "listening" TCP stream to receive calls.
Like in ITK_TCPOpen, control is returned immediately without waiting for a connection to be received and established.
Use ITK_TCPStatus or ITK_TCPWaitConn to wait for the connection to be established.

Use tcpOpt to create an SSL "server" stream instead of a TCP stream (added in ITKv2.5).

If localPort is equal to 443 (HTTPS standard port number), ITK will switch automatically to SSL.

SSL "server" is only available in the "Pro" version of ITK with an additional SSL server license.


Note:

Under MacOS X, your application needs to run with root privileges in order to listen on ports ranging from 1 to 1023.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

hostFilter

 

Longint

 

TCP address of remote host

Pass 0 to accept connections from any remote host, otherwise pass a numeric IP address to only accept connections from the specified remote host.

->

portFilter

Integer

TCP remote port

Pass 0 to accept connections from any remote port numbers, otherwise pass a port number to only accept connections from the specified port number (ex: 80 for HTTP, 25 for SMTP, see RFC#1700 for assigned numbers).

->

localPort

Integer

local port number

Pass the local port number on which you want to listen for incoming connections (ex: 80 for HTTP, 25 for SMTP, see RFC#1700 for assigned numbers).

->

rcvBuffer

Longint

Receive buffer size for this stream

This parameter is used only under MacTCP.
Accepts values between 8192 and 32767.
Pass 0 for ITK to use a default buffer of 8KB (8192 bytes).

->

tcpOpt

Longint

TCP options (type of service field, leave 0 as default)

This parameter is used only under MacTCP.
See MacTCP Programmer's Manual for more details on the "type of service" values.

option 2048 indicates that an SSL "server" stream should be created instead of a classical TCP stream (added in ITKv2.5)

->

oldStream

Longint

 

old stream reference number to reuse (pass 0 to allocate a new stream)

This parameter is obsolete and shouldn't be used anymore.

->

localIP

Longint

local IP address
This parameter is provided for multihoming support.

Pass 0 if you want to accept incoming connections on all local IP addresses, otherwise, pass one of the local IP addresses to only accept incoming connection on the specified IP address.

<-

streamRef

Longint

stream reference number

Will return 0 if the stream couldn't be created.


Example:

` create a TCP listening stream on HTTP port
$stream := ITK_TCPListen(0;0;80) ` listen on HTTP port number
If ($stream#0)
  ...
  $err := ITK_TCPRelease($stream)
End If
         
` create an SSL listening stream on HTTPS port
$stream := ITK_TCPListen(0;0;443;0;2048) ` listen on HTTPS port number
If ($stream#0)
  ...
  $err := ITK_TCPRelease($stream)
End If
Back to top


ITK_TCPClose

Syntax:

error := ITK_TCPClose (streamRef)


Description:

Sends the data remaining in the output buffer (see ITK_TCPSend ) and tells the remote host that no more data will be sent.
After closing a stream, you can still receive data on it until you use ITK_TCPRelease .
This is possible because a TCP stream is made of two half streams, each one used to send data from one host to the other. Each half-stream can be closed separately (also called half-close).


Warning:

Closing a stream doesn't releases the stream, but only tells the remote host that you're done sending data.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

<-

error

Longint

error code

0 = no error
-1 = invalid stream reference number


Example:

$stream := ITK_TCPOpen("www.internet-toolkit.com";80)
If ($stream#0)
  ...
  $err := ITK_TCPClose($stream)
  ...
  $err := ITK_TCPRelease($stream)
End If
Back to top


ITK_TCPRelease

Syntax:

error := ITK_TCPRelease (streamRef; optionFlag)


Description:

Releases a TCP stream and all its associated buffers.
After this call, the streamRef should not be used anymore.


Note:

When calling ITK_TCPRelease , all data remaining to be sent will not be sent. To avoid this, you must call ITK_TCPClose and then monitor ITK_TCPStatus to check that the remote host has received all remaining data and that you closed your half-stream.

Each successfull calls to ITK_TCPOpen and ITK_TCPListen must be balanced by a call to ITK_TCPRelease.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

optionFlag

Longint

Optionnal flag

0 = no option
1 = obsolete flag
2 = force internal listener to stop listening

<-

error

Longint

error code

0 = no error
-1 = invalid stream reference number


Example:

$stream := ITK_TCPOpen("www.internet-toolkit.com";80)
If ($stream#0)
  ...
  $err := ITK_TCPRelease($stream)
End If
Back to top


ITK_TCPStatus

Syntax:

status := ITK_TCPStatus (streamRef;selector)


Description:

Returns the current status of a TCP stream or miscellaneous information about the stream.
Use it to wait for a connection to be established (status=8) or for the remote host to acknowledge a half-close.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number or global info selector

Stream reference number as returned by ITK_TCPOpen , or ITK_TCPListen .

Global info selectors:

  • -1 = round trip average*
  • -2 = minimum round trip time*
  • -3 = maximum round trip time*
  • -4 = maximum TCP segment size*
  • -5 = maximum TCP connections
  • -6 = number of connection attempts
  • -7 = number of connections opened
  • -8 = number of connections accepted
  • -9 = number of closed connections
  • -10 = number of aborted connections
  • -11 = bytes received
  • -12 = bytes sent
  • -13 = duplicate bytes received*
  • -14 = retransmitted bytes*
  • -15 = number of packets received*
  • -16 = number of packets sent*
  • -17 = number of duplicate packets received*
  • -18 = number of packets retransmitted*

* information only available under MacTCP.

->

 

selector

 

Longint

 

selector value

  • 0 = ITK_TCPStatus will return the current status of streamRef
  • 1 = sendWindow will be returned*
  • 2 = rcvWindow will be returned*
  • 3 = amtUnackedData will be returned*
  • 4 = amtUnreadData will be returned*
  • 5 = sendUnacked will be returned*
  • 6 = sendNext will be returned*
  • 7 = congestionWindow will be returned*
  • 8 = rcvNext*
  • 9 = srtt*
  • 10 = lastRTT*
  • 11 = dataPktsRcvd*
  • 12 = dataPktsSent*
  • 13 = dataPktsResent*
  • 14 = bytesRcvd**
  • 15 = bytesRcvdDup*
  • 16 = bytesRcvdPastWindow*
  • 17 = bytesSent**
  • 18 = bytesResent*
  • 19 = lastRTT*
  • 20 = tmrSRTT*
  • 21 = rttVariance*
  • 22 = tmrRTO*
  • 23 = SSLrawRcvd**
  • 24 = SSLrawSent**

* information only available under MacTCP.

**With SSL streams, bytesRcvd and bytesSent indicate the number of SSL data transmitted, SSLrawRcvd and SSLrawSent indicate the total raw bytes of encrypted data really transmitted at the TCP/IP layer level.

<-

status

Longint

current stream status code

-1 = invalid streamRef error
other negative values = any other error

Positive values are current status:

0

Closed

no connection exists on this stream

2

Listen

listening for an incoming connexion.

4

SYN received

incoming connection is being established

6

SYN sent

outgoing connection is being established

8

Established

connection is up

10

FIN Wait 1

connection is up; close has been sent

12

FIN Wait 2

connection is up; close has been sent and acknowledged

14

Close Wait

connection is up; close has been received

16

Closing

connection is up; close has been issued and received

18

Last ACK

connection is up; close has been issued and received

20

Time Wait

connection is being broken

see RFC#793, page 21 


Example:

` wait for the connection to be established
Repeat
  $s := ITK_TCPStatus($stream)
  IDLE
Until (($s>=8) | ($s<0))  ` end if connected or error
Back to top


ITK_TCPStatus2A

Syntax:

index := ITK_TCPStatus2A (arrStreams;arrStatus;minStatus)


Description:

Returns the current status of an array of streams and the index of the first stream which status is greater than or equal to minStatus, or negative (error on the stream).

This routine can be used to monitor the status of a list of streams and wait for a connection or a close to be acknowledged.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

arrStreams

 

Array
of
Longint

a list of stream reference numbers

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

 

arrStatus

 

Array
of
Longint

 

selector value

-1 = invalid streamRef error
other negative value = any other error

Positive values are current status:

0

Closed

no connection exists on this stream

2

Listen

listening for an incoming connexion.

4

SYN received

incoming connection is being established

6

SYN sent

outgoing connection is being established

8

Established

connection is up

10

FIN Wait 1

connection is up; close has been sent

12

FIN Wait 2

connection is up; close has been sent and acknowledged

14

Close Wait

connection is up; close has been received

16

Closing

connection is up; close has been issued and received

18

Last ACK

connection is up; close has been issued and received

20

Time Wait

connection is being broken

see RFC#793, page 21

->

minStatus

Longint

status value to reach

   

<-

index

Longint

first item in array to reach

Will return the item number of the first stream that reaches minStatus or some error code (negative value).


Example:

ARRAY LONGINT($streams;10)
ARRAY LONGINT($status;10)
 
For ($i;1;10)
  $streams{$i} := ITK_TCPListen(0;0;80)
End For
 
` wait for the connection to be established on a list of streams
Repeat
  $i := ITK_TCPStatus2A($streams; $status; 8)
  If ($i>0)
    $s := ITK_TCPStatus($streams{$i})
    Case of
    :($s >= 8) ` stream connected
      ... ` handle the HTTP hit
    :($s<0) ` error on stream
      $err := ITK_TCPRelease($streams{$i})
      $streams{$i} := ITK_TCPListen(0;0;80)
    ...
    End Case
  End If
Until (quit)
Back to top


ITK_TCPSend

Syntax:

result := ITK_TCPSend (streamRef;data;flushFlag;filterFlag)


Description:

Sends data through an established TCP stream.
ITK has its own send buffer which helps reducing the number of calls to lower level TCP/IP layers when small chunks of data are sent.
Filtering can be applied on the sent text.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

data

Text

data to send

   

->

flushFlag

Integer

 

   

0 = don't use ITK output buffer, flush its content if it wasn't empty,
1 = use ITK's output buffer. It will be flushed regularly by ITK.
Values above 255 indicate the maximum number of bytes that may be buffered. If the output buffer contains more than the value passed, ITK will flush its output buffer.
ITK's send buffer will also be flushed when calling ITK_TCPRcv or ITK_TCPClose .

->

filterFlag

Longint

   

One or more encodings can be applied before sending the data (or putting them in ITK's send buffer). You may add flag values to apply several filters.
See Table#1 for all filter flag values.

->

result

Longint

   

Returns the number of bytes currently stored in ITK's output buffer.

Negative values indicates that an error occurred on this stream (it may have been released by the remote host).


Example:

$stream := ITK_TCPOpen("www.internet-toolkit.com";80)
If ($stream#0)
  ... ` wait for connection to be established
  ` use ITK's send buffer
  $err := ITK_TCPSend($stream;"GET / HTTP/1.0"+$crlf;1)
  ` Flush ITK's send buffer
  $err := ITK_TCPSend($stream;"User-Agent: myWebBrowser/1.0"+$crlf+$crlf)
  ...
 
Back to top


ITK_TCPRcv

Syntax:

result := ITK_TCPRcv (streamRef;dataStorage;maxLen;filterFlag;appendFlag;endString;timeout)


Description:

Receives data through an established TCP stream.
Remaining data in ITK's send buffer is sent if present.
Filtering can be applied on the received text.

ITK_TCPRcv will return control immediately when the timeout is set to 0.

When the timeout is not 0, ITK_TCPRcv will return when one of these conditions is valid:

  • endString (if not empty) is received (and according to the options flag),
  • maxlen bytes have been received (if maxlen is not 0),
  • data have been received and no maxlen is specified (or left to 0),
  • timeout is over,
  • the length of dataStorage is greater or equal to 32000 bytes.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

dataStorage

Text

storage variable or field

Content is replaced or appended depending on appendFlag

->

maxLen

Integer

 

maximum length of data to be received

Pass 0 if you want to receive all available data (up to 32000 bytes which is the limit for Text fields or variables in 4D).

->

filterFlag

Longint

   

One or more encodings can be applied before sending the data (or putting it into ITK's receive buffer). You may add flag values to apply several filters at once.
See Table#1 for all filter flag values.

->

options

Longint

 

Options can be combined, ex:
5 = 1+4 = append + search in new data

0 = do not append received data to previous data present in dataStorage
1 = append received data to previous data present in dataStorage

Version 2.0.3 and above:
2 = the ending string will remain in ITK's receive buffer
4 = do not search endstring in original data when append is used

->

endString

String

end receive string

If this string is found in incoming data or accumulated data (when the append flag is used), ITK_TCPRcv will return all data up to this string (including it), remaining data will be kept in ITK's receive buffer.

->

timeout

Longint

maximum time to wait for endString (in 1/60th of a second)

Special values:
-1 = infinite time
0 = returns control immediately

<-

result

Longint

returns number of bytes received or any error code (negative value).

-1 = invalid stream reference number


Example:

$stream := ITK_TCPOpen("mail.internet-toolkit.com";25)
if ($stream#0)
  ... ` wait for connection to be established
  $rcvdLen := ITK_TCPRcv($stream; $data)
  ...
 

In the following example, the first call to ITK_TCPRcv will receive data until a pair of CR/LF during a maximum of 2 minutes.

Then the second call to ITK_TCPRcv will append received data into http_req until a <>CRLF is received in new data received or $len data are accumulated in http_req during a maximum of 2 minutes.

` Receive HTTP header
$err := ITK_TCPRcv($c;http_req;32000;0;<>CRLF+<>CRLF; 2*60*60)
...
If (http_req = "POST @")
  $err := ITK_TCPRcv($c;http_req;$len;1+4;<>CRLF;2*60*60) ` receive "POST" data
  ...
         
Back to top


ITK_TCPChRcv

Syntax:

result := ITK_TCPChRcv (streamRef)


Description:

Returns the number of bytes available in the receive buffer of a TCP stream.


Note:

The number of bytes received after calling ITK_TCPChRcv may be greater than the value returned by ITK_TCPChRcv as some data may have been received between the two calls.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

<-

result

Longint

number of bytes (positive values) or error code (negative values)

-1 = invalid stream reference number


Example:

if (ITK_TCPChRcv($stream)#0) ` do we have some data available ?
  $result := ITK_TCPRcv($stream;$buff)
  ...
 
Back to top


ITK_TCPUnRcv

Syntax:

result := ITK_TCPUnRcv (streamRef;data; options)


Description:

ITK_TCPUnRcv can be used to put some data you previously received back into ITK's receive buffer.
This data will be received in the next call to receiving routines (like ITK_TCPRcv , ITK_TCPRcvBlob , ITK_TCPRcvFile , etc.).


Notes:

The options flags parameter has been added in v2.0.4.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

data

Text

data to put back in ITK's receive buffer

   

->

option

Longint

optional flags

0 = put data at the END of the "unreceive buffer"
1 = put data at the BEGINING of the "unreceive buffer"

Parameter added in v2.0.4

<-

result

Longint

error code

0 = no error
-1 = invalid stream reference number


Example:

$result := ITK_TCPRcv($stream; $data) ` receive some data
if ($data # "+OK@")
  $err := ITK_TCPUnRcv($stream;$data) ` put it back in ITK's buffer to receive it again
 
Back to top


ITK_TCPStrmInfo

Syntax:

error := ITK_TCPStrmInfo (streamRef; remoteIP; remotePort; localPort; srtt; localIP)


Description:

Returns information about an established TCP stream.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

<-

remoteIP

Longint

IP address of the remote host

Content is replaced or appended depending on appendFlag

<-

remotePort

Integer

 

Port number used by the remote host

Pass 0 if you want to receive all available data (up to 32000 bytes which is the limit for Text fields or variables in 4D).

<-

localPort

Integer

Local port number

One or more encodings can be applied before sending the data (or putting it into ITK's receive buffer). You may add flag values to apply several filters at once.
See Table#1 for all filter flag values.

<-

srtt

Longint

 

Smoothed round trip time

This value is only available under MacTCP, otherwise -1 is returned.

<-

localIP

Longint

Local IP address

This value is useful for multihomed systems (like Windows NT or MacOS with OpenTransport 1.3 or above).

On non multihomed system, the local IP address is always returned.

<-

error

Longint

   

0 = no error
-1 = invalid stream reference number


Example:

$err := ITK_TCPStrmInfo($stream;remAddr;remPort;locPort;srtt;locAddr)
ALERT("Remote host address: "+ITK_Addr2Name(remAddr;2))
 

Note:

localPort and remotePort may return negative values, because 4D is using signed integers.

To get the original positive port number, you can use the following code:

C_LONGINT(locPort; remPort) ` MUST be typed as LONGINTS !!!
$err :=
ITK_TCPStrmInfo ($stream;remAddr;remPort;locPort;srtt;locAddr)
If (locPort < 0)
locPort := locPort + 65536
End if

If (remPort < 0)
remPort := remPort + 65536
End if

Back to top


ITK_TCPWaitConn

Syntax:

result := ITK_TCPWaitConn (streamRef;minStatus;timeout)


Description:

Wait for a TCP stream to be in a certain status or to return an error (negative value).
This routine can be used to wait for a stream to establish connection.

This routine is synchronous, control will be returned:

  • when the stream status is greater or equal to minStatus,
  • when timeout expires,
  • or when some error occurs with the stream.


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

minStatus

Longint

minimum status value to wait for

   

->

timeout

Longint

maximum time to wait (in seconds)

0 = wait indefinitely

<-

result

Longint

stream's status or error code (negative values).

-1 = invalid stream reference number


Example:

$stream := ITK_TCPOpen("mail.internet-toolkit.com";25)
` wait for connection to be established 
$status := ITK_TCPWaitConn($stream;8;10) ` wait 10 seconds
If ($status=8)
  ...
End If
$err := ITK_TCPRelease($stream)
 
Back to top


ITK_SetTimeout

Syntax:

curTimeout := ITK_SetTimeout (streamRef;newTimeout)


Description:

ITK_SetTimeout can be used to set the default timeout used by all "send" ITK routines (ITK_TCPSend, ITK_TCPSendFile, ITK_TCPSendPict, ITK_TCPSendBlob).

By default, ITK doesn't use any timeout when sending data. It can be usefull to set a timeout to avoid possible "send locks" when the remote host becomes unreachable (crash or disconnection for example).

When the send timeout is reached in one of the ITK_TCPSend routines, the routine will return control , but the status of the stream will remain the same.

The best place to set the timeout for a given stream is just after a successfull call to ITK_TCPOpen or ITK_TCPListen .


Params:

In/Out

Parameter

Type

   

Example or note

->

 

streamRef

 

Longint

 

stream reference number

As returned by ITK_TCPOpen , or ITK_TCPListen .

->

newTimeout

Longint

timeout value in ticks (1/60s)

0 = no timeout (default ITK behaviour)

<-

curTimeout

Longint

new current timeout value (in seconds)

   


Example:

$stream := ITK_TCPOpen("mail.internet-toolkit.com";25)
if ($stream#0)
  ` all ITK_TCPSend calls will have a 2mn timeout
  $curTimeout := ITK_SetTimeout($stream;2*60*60)
  ...
Back to top


CQ/26-Aug-2002