Socket

From Remeis-Wiki
Jump to navigation Jump to search

tcp_server and tcp_client

The main functions of the socket-module are socket, bind, listen, accept, and connect. The ISISscripts functions tcp_server and tcp_client use these functions to provide a simple server-client-implementation.

Example: quick_send and quick_get

As an example usage for these functions, you can find the code of quick_send and quick_get here:

% LAYOUT
% 
% quick_send      quick_get
% tcp_server  ->  tcp_client
%

% global variable for the object: we need this globally to
% use the object during the hook functions (e.g., _quick_send)
private variable _quick_obj = NULL;
% name of the receiver (quick_send) or the sender (quick_get)
private variable _quick_host = "";

% greet_hook of quick_get (tcp_client): check the greet message of
% the server, which should be its hostname
define _quick_get_greet(c, greet) {
  if (greet == _quick_host) { return getenv("HOST"); }
  return 0;
}

%%%%%%%%%%%%%%%%%%%%
define quick_get()
%%%%%%%%%%%%%%%%%%%%
%!%+
%\function{quick_get}
%\synopsis{gets an SLang object sent from another machine}
%\usage{Any_Type quick_get(String_Type from_host);}
%\example
%    % receive an object from 'indus'
%    variable obj = quick_get("indus");
%\seealso{quick_send, tcp_client}
%!%-
{
  switch (_NARGS)
    { case 1: (_quick_host) = (); }
    { help(_function_name); return; }

  variable client;
  % try to connect to the sender until a connection is established
  do {
    client = tcp_client(
      _quick_host;
      chatty = 0,
      greet_hook = &_quick_get_greet % use user-defined greet message (see above)
    );
    % client == 0 -> connection failed, e.g., server is not running
    if (typeof(client) == Integer_Type && client == 0) { sleep(1); }
  } while (typeof(client) != Struct_Type);
  % connection is established
  if (typeof(client) == Struct_Type) {
    % receive the object
    client.config.chatty = 1; % enabled progress bar
    _quick_obj = client.receive();
    client.config.chatty = 0; % disable further messages
    % disconnect from the server
    ()=client.disconnect();
    % return the object
    return _quick_obj;
  }
}

% established_hook of quick_send (tcp_server): send the object and
% shut down the server afterwards
private define _quick_send(s, c) {
  c.config.chatty = 1; % temporarily enable progress bar
  ()=c.send(_quick_obj);
  ()=s.shutdown();
}

% greet_hook of quick_send (tcp_server):
% 1) define the greet message to be sent to the client, which is
%    the server's hostname
% 2) check if the re-greet message is equal to the expected receiver
private define _quick_send_greet() {
  variable s, c, greet = NULL;
  switch (_NARGS)
    % send greet message
    { case 2:
      (s,c) = ();
      return getenv("HOST");
    }
    % check greet message
    { case 3:
      (s,c,greet) = ();
      if (greet == _quick_host) { return 1; }
      % greet not accepted -> trigger the shutdown of the server
      % after execution of its main loop 
      ()=s.shutdown(; trigger);
      return 0;
    }
}

%%%%%%%%%%%%%%%%%%%%
define quick_send()
%%%%%%%%%%%%%%%%%%%%
%!%+
%\function{quick_send}
%\synopsis{sends an SLang object to another machine}
%\usage{quick_send(String_Type to_host, Any_Type object);}
%\example
%    % send an array of doubles to 'ara'
%    quick_send("ara", Double_Type[10000]);
%\seealso{quick_get, tcp_server}
%!%-
{
  switch (_NARGS)
    { case 2: (_quick_host, _quick_obj) = (); }
    { help(_function_name); return; }

  ()=tcp_server(;
    maxclients = 1,
    chatty = 0,
    greet_hook = &_quick_send_greet, % use user-defined greet message (see above)
    established_hook = &_quick_send  % send the object by this hook
  );
}