Help / JforC / Socket Programming

From J Wiki
Jump to navigation Jump to search


>> << Pri JfC LJ Phr Dic Voc !: Rel NuVoc wd Help J for C Programmers


                                                                                                22. Socket Programming

J provides the standard set of socket functions.  This chapter assumes you already understand socket programming and provides a description of J's facilities.

First, you must load the script that defines the socket interface:

   require 'socket'

(require is like load but if the file has already been loaded it does nothing).  This will define a number of variables inside J.  You must make the variables visible to your program, and the easiest way to do that is with the verb DefSockets defined in system\packages\misc\jforc.ijs:

   DefSockets ''

You are then ready to create a socket:

   sdsocket AF_INET,SOCK_STREAM,0
+-+--+
|0|96|
+-+--+

sdsocket returns return_code;socket_number .  Nonzero return codes indicate errors; look in J_directory/system/main/socket.ijs for definitions.  The valid address families and socket types are defined in J_directory/system/main/defs/netdefs_YourOS.ijs.

sdselect

You check the status of sockets with

   sdselect read_list;write_list;error_list;maxtime

The three lists are lists of sockets and maxtime is a time in milliseconds.  sdselect will delay for a maximum of maxtime milliseconds until it sees a socket in read_list that is ready for reading, or one in write_list that is ready for writing, or one in error_list that has an error.  When it finds a qualifying socket, or when the time limit is reached, it returns

result_code;read_ready_list;write_ready_list;error_list

which lists all the qualifying sockets.  A maxtime of 0 always returns immediately, giving the current status of the specified sockets.

If sdselect is invoked with an empty operand (sdselect ), it checks all sockets with a maxtime of 0.

Asynchronous Sockets and socket_handler

By default, sockets created by sdsocket are blocking sockets; an operation on such a socket waits until data is available.  This can tie up your J session while the remote computer is responding, so if you are serious about your socket programming you will want to make your sockets nonblocking.  You do so with

   sdasync socket_number

which marks that socket as nonblocking and requests notification of changes in its status.  All operations to a nonblocking socket return immediately (with the error code EWOULDBLOCK if the operation cannot be immediately completed).  When there is a change in the status of a nonblocking socket, the interpreter executes

   socket_handler ''

and it is up to you to have a socket_handler defined that will use sdselect to see what sockets are ready for transfers and then execute those transfers.

Names and IP Addresses

Sockets are addressed by IP address and port number.  To translate a domain name to an IP address, use

   sdgethostbyname domain_name

for example,

   sdgethostbyname 'www.jsoftware.com'
+-+-+---------------+
|0|2|216.122.139.159|
+-+-+---------------+

where the result is return_code;address_family;address .  If the domain is unknown an address of '255.255.255.255' is returned.

   sdgethostbyaddr address_family;address

will translate an IP address back to a domain name.

The name of your machine is given by

   sdgethostname ''
+-+-----+
|0|1qfe3|
+-+-----+

(result is return_code;name) so you can get your own IP address by

   sdgethostbyname 1 {:: sdgethostname ''
+-+-+-----------+
|0|2|65.80.203.8|
+-+-+-----------+

If you have a socket with an active connection you can get some information about the machine on the other end with

   sdgetpeername socket_number
+-+-+------------+--+
|0|2|64.58.76.229|80|
+-+-+------------+--+

where the result is return_code;address_family;remote_IP_addr;remote_port .

You can get information about your own end of a connected socket with

   sdgetsockname socket_number
+-+-+-----------+----+
|0|2|65.80.203.8|2982|
+-+-+-----------+----+

where the result is return_code;address_family;local_IP_addr;local_port .

Connecting

Reading from a Web site, you use the sequence sdsocket/sdconnect/sdsend/sdrecv/sdclose .

   sdconnect socket;address_family;IP_addr;port

will connect your socket to the remote machine addressed by address_family;IP_addr;port .  If the socket is blocking, sdconnect completes when the connection has been made.  If the socket is nonblocking, sdconnect will return immediately with the error code EWOULDBLOCK and socket_handler will be called when the connection has been made.  An example is

   sdconnect 184;2;'64.58.76.229';80

With the connection established, you can send data with

   data sdsend socket;flags

where the flags are any of the MSG_ values from socket.ijs, usually 0.  The result is return_code;number_of_bytes_sent .  Fewer bytes may be sent than were in your data; you will have to resend the excess.

You receive data with

   sdrecv socket,count,flags

where count is the maximum number of bytes you will accept and flags are any of the MSG_ values from socket.ijs, usually 0.  The result is return_code;data .  If the socket is blocking, sdrecv will wait until it is ready for reading; if the socket is nonblocking, sdrecv will immediately return (presumably you issued the sdrecv only after using sdselect to verify that the socket was ready for reading).  In either case, sdrecv will return with data if it has any; if the length of data is 0, that means that the connection was closed by the peer and all data sent by the peer has been received.

When you have finished all you data transfers for a socket, ,you must close it with

   sdclose socket

which has as result an unboxed return_code .

Listening

If you want to wait for a remote machine to get in touch with you, use the sdbind/sdlisten/sdaccept sequence instead of sdconnect .  The sequence is:

   sdbind socket;address_family;IP_addr;port

to establish a connection between the socket and the address given by address_family;IP_addr;port .  If IP_addr is , the socket can be used to listen for a connection to any address on the machine.  If port is 0, the system will assign a port number.  The result of sdbind is an unboxed return_code .

   sdlisten socket;connection_limit

causes the operating system to start listening for connections to the address bound to socket .  The result is an unboxed return_code .A maximum of connection_limit connections can be queued awaiting sdaccept .  When a connection is made to a listening socket's address, the socket is shown in sdselect as ready to read, and you should issue

   sdaccept socket

which will return return_code;clone_socket where clone_socket is a new socket, with all the attributes of socket but additionally with a connection to the remote host.  You should direct all your sdsend, sdrecv, and sdclose operations to the clone_socket .

Other Socket Verbs

Datagrams

The sequences given above apply to sockets of type SOCK_STREAM, e. g. TCP sockets.  Connectionless sockets with type SOCK_DGRAM are also supported, and could be used for UDP transfers.  The verbs to use to transfer datagrams are

   sdrecvfrom socket;count;flags

where count is the maximum number of bytes you will accept and flags are any of the MSG_ values from socket.ijs, usually 0.  The result is return_code;data;sending_address .  If the socket is blocking, sdrecvfrom will wait until it is ready for reading; if the socket is nonblocking, sdrecvfrom will immediately return (presumably you issued the sdrecvfrom only after using sdselect to verify that the socket was ready for reading).  The returned data is the datagram, which may have a length of 0.

   data sdsendto socket;flags;address_family;IP_addr;port

where the flags are any of the MSG_ values from socket.ijs, usually 0.  The datagram is sent to the remote address given by address_family;IP_addr;port, and the result is return_code;number_of_bytes_sent .

Socket Options

Verbs to query and set socket options are

   sdgetsockopt socket;option_level;option_name

with result return_code;option_value .  Examples:

   sdgetsockopt sk;SOL_SOCKET;SO_DEBUG
   sdgetsockopt sk;SOL_SOCKET;SO_LINGER
   sdsetsockopt socket,option_level,option_name,value_list

(note that the operand is an unboxed list)  The option is set, and the result is return_code;option_value .  Examples:

sdsetsockopt sk,SOL_SOCKET,SO_DEBUG,1
sdsetsockopt sk,SOL_SOCKET,SO_LINGER,1 66
   sdioctl socket,option,value

reads or sets control information (result is return_code;value).  Examples:

   sdioctl sk,FIONBIO,0  NB. set blocking
   sdioctl sk,FIONBIO,1  NB. set non-blocking
   sdioctl sk,FIONREAD,0  NB. count ready data

Housekeeping

   sdgetsockets  ''

The result is return_code;list_of_all_active_socket_numbers .

   sdcleanup ''

All sockets are closed and the socket system is reinitialized.  The result is .


>> << Pri JfC LJ Phr Dic Voc !: Rel NuVoc wd Help J for C Programmers