Win32forth Socket Library

Simple Socket Library

Tom Dixon

This is intended to be a simple wordset for sockets in forth. The words do not match the standard socket api. It has been adapted to be easier to use in Forth. It's simplicity should make it easy to port network apps to other forth systems.

Network Formatting Words

These words are for converting 16-bit and 32-bit values to the right format so any machine should be able to convert them back into their values.

1 PROC htonl ( hostlong -- u_long )

Convert a 32-bit number on the stack to a network acceptable byte-ordered value.

1 PROC htons ( hostshort -- u_short )

Convert a 16-bit number on the stack to a network acceptable byte-ordered value.

1 PROC ntohl ( netlong -- u_long )

Convert a network compatible 32-bit number on the stack to the correct 32-bit integer

1 PROC ntohs ( netshort -- u_short )

Convert a network compatible 16-bit number on the stack to the correct 16-bit integer

Socket Library and Initialization Words

These words are for initializing and unloading the windows socket dll. They are automatically called when the console is initialized and right before it closes, so normally a developer would never need to use these.

: wsocket2-init ( -- ) 

Initializes the windows socket dll

called in initialization-chain

: wsocket2-cleanup ( -- )

Initializes the windows socket dll

called in initialization-chain

Main Socket Words

These words represent the core of the socket library. They have been written to be thread-safe.

: host>iaddr ( str len -- iaddr )

This function converts a host string to an ip address

The host string could be anything from a domain name to ip address.

Returns 0 if the host is unable to be looked up.

: iaddr>str ( iaddr -- str len ) 

This converts an ip address to a readable string. It does not look up the host name, the string is in the "255.255.255.255" format



Example: simple host lookup.

s" www.win32forth.org" host>iaddr
dup . \ should be anything other than 0
iaddr>str type \ should return ip address of win32forth.org
: sock-open ( addr len port -- sock )

This opens up a new socket to a host name on a given port number

the host name will be looked up and the port number is converted implicitly

If the socket cannot be opened, a exception will be thrown.

: sock-read ( addr len sock -- len ) 

Reads data from the socket to a buffer.

It works very similarly to 'read-file', but has different return parameters

a returned 'len' of -1 means there was a socket error (SOCKET_ERROR)

If the provided 'len' is larger than the amount of data ready to be read from the socket, the socket will block until it has revceived the full amount of data.

If the socket is a non-blocking socket, it will read what it can and return right away.

: sock-write ( addr len sock -- len ) 

Write data from a buffer to the socket.

It works very similarly to 'write-file'

a returned 'len' of -1 means there was a socket error (SOCKET_ERROR)

If the socket is currently unable to take any data, the socket will block until it has room in it's internal buffer to send the data.

If the socket is a non-blocking socket, it will write what it can and return right away. (amount actually written is returned as 'len')

: sock-close ( sock -- ior )

Closes socket - very similar to close-file

ior is 0 if the close was successful



Example: Get data from a socket.

This will dump the html data from google's homepage through the use of sockets.

create tbuf 256 allot
0 value sock
: sdump ( sock -- )
  begin
    dup sock-read? if dup tbuf 256 rot sock-read tbuf swap type then
    dup sock-closed? key? or until
  sock-close drop ;

s" www.google.com" 80 sock-open value sock
s" GET / HTTP/1.0" sock sock-write .
crlf$ count sock sock-write .
crlf$ count sock sock-write .
sock sdump

Socket Listening Words

These words are for writting the serving-end of network applications.

They have also been written to be thread-safe.

: sock-create ( p -- sock )

Make a new socket for listening on port 'p' Used only for server-side sockets

: sock-listen ( n sock -- )  

This tells a socket to start queuing sockets that want to connect.

'n' is the size of the queue that should be created to listen. after 'n' sockets have tried to connect and have yet to be accepted, further sockets will be refused until waiting sockets are accepted. (standard queue size is 5)

: sock-accept ( sock -- sock iaddr ) 

This will accept a socket that is in the listening queue.

'iaddr' is the ip address of the connecting socket and can be converted into an easy-to-read number through the 'iaddr>str' word.

If no sockets are in queue to be accepted, this function will block until one tries to connect.

If the socket is a non-blocking socket, then the function will fail and return immediately if the queue has no sockets to accept.

If the function fails, it will return '0' as the iaddr and '-1' (or INVALID_SOCKET) as the socket.

Asyncronous Socket Words

These words are for the ability to use the sockets without having them block.

Very useful for apps that need to do many things at once.

: sock-read? ( sock -- n )

This function returns the amount of data that the socket can read without blocking. It is useful for working with socket asyncronously.

It will return -1 if the socket has no data to read (will block, or socket closed).

: sock-write? ( sock -- flag )

This function returns true if the socket can write data without blocking.

You can send 0-1024 bytes to the socket asyncronously without blocking if the flag is true.

: sock-accept? ( sock -- flag )

This function returns true if the socket has other sockets in queue that want to be connected. It is to be used in conjunction with 'sock-accept' so you can call sock-accept without blocking.

: sock-closed? ( sock -- flag ) 

This function tests to see if the socket has been closed at the other end or broken at any point.

: sock-err? ( sock -- n )

This function tests to see if there are any errors on the socket.

: sock-blocked ( flag sock -- )

This function sets a socket to blocked or unblocked mode.

If the flag is false, the socket will be set to 'unblocked'.

If the flag is true, the socket will be set to 'blocked'.


(original article from Tom Dixon, published at : http://win32forth.sourceforge.net/doc/Sock.htm)