/* Name: Linda-client for Java Author: K.Y. Hui Version: 1.02 Date: 12 November 1997 */ package Linja; import java.io.*; import java.net.*; /* Constructors: LindaClient() LindaClient(String host,int port) Methods: void connect(String host,int port) throws SocketException, UnknownHostException, IOException void disconnect() throws IOException boolean set_timeout(int millisecond) boolean set_protocol(char protocol) void out(String item) throws IOException String in(String template) throws IOException, InterruptedIOException String in(String[] templates) throws IOException, InterruptedIOException String in_noblock(String template) throws IOException String rd(String template) throws IOException, InterruptedIOException String rd(String[] templates) throws IOException, InterruptedIOException String rd_noblock(String template) throws IOException */ public class LindaClient { private char protocol='p'; //'p' or 'f' private String host=null; //host name of connection private int port=0; //socket port no. private int timeout=5000; //default timeout value private boolean connected=false; //connection status flag private Socket socket=null; //the socket private BufferedReader in_stream=null; //input stream private BufferedWriter out_stream=null; //output stream // // constructor without host:port // will be specified when connecting // public LindaClient() { host=null; port=0; } // // constructor with host:port // public LindaClient(String host,int port) { this.host=host; this.port=port; } // // object finalizer // protected void finalize() throws IOException { if (socket!=null) disconnect(); } // // connect without host:port // take host:port during creation // // NB: socket is not created until connecting // public void connect() throws SocketException, UnknownHostException, IOException { connect(host,port); } // // connect with host:port // // NB: socket is not created until connecting // public void connect(String host,int port) throws SocketException, UnknownHostException, IOException { if (host==null) { throw new UnknownHostException("no host specified"); } //create socket socket=new Socket(host,port); //create streams in_stream=new BufferedReader(new InputStreamReader(socket.getInputStream())); out_stream=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); socket.setSoTimeout(timeout); //set default socket timeout if (!ping()) { disconnect(); //if ping fail, disconnect throw new SocketException("fail in PING"); } } // // disconnect from connection // public void disconnect() throws IOException { in_stream.close(); //close streams out_stream.close(); socket.close(); //and socket } // // set communication timeout value // public boolean set_timeout(int millisec) { try { socket.setSoTimeout(millisec); } catch (SocketException e) { return(false); } timeout=millisec; return(true); } // // set protocol to use (p or f) // public boolean set_protocol(char prot) { if (prot!='p' && prot!='f') { System.err.println("ERROR: protocol ust be 'p' or 'f'"); return(false); } protocol=prot; return(true); } // // ping Linda server & wait for reponse using the default protocol // protected boolean ping() { return(ping(protocol)); } // // ping Linda server using the specified protocol // protected boolean ping(char prot) { String answer; try { to_linda(prot,"ping"); } catch (IOException e) { return(false); } try { answer=from_linda(prot); } catch (InterruptedIOException e) { System.err.println("ERROR: timeout in response"); return(false); } catch (IOException e) { System.err.println("ERROR: error reading from socket"); return(false); } return(answer.equalsIgnoreCase("pong")); //check for "pong" } // // send to Linda connection // private void to_linda(char code,String data) throws IOException { to_linda(protocol,code,data); //send using default protocol } // // send a string array to the Linda server // private void to_linda(char code,String[] data_list) throws IOException { StringBuffer all=new StringBuffer("["); //start with the left bracket int i; // compose a string representing a Prolog list for (i=0;i0) { all.append(data_list[data_list.length-1]); } all.append("]"); //end of list to_linda(code,new String(all)); //send the string to Linda } // // send to Linda using the specified protocol // private void to_linda(char prot,char code,String data) throws IOException { //call appropriate method according to protocol if (out_stream==null) { System.err.println("ERROR: output stream not opened"); throw new IOException("fail writing to Linda"); } if (prot=='p') { out_stream.write('p'); //send protocol 1st out_stream.write(code); //send command code out_stream.write(data,0,data.length()); //send data string out_stream.write('.'); //the Prolog period out_stream.write('\n'); //send newline // out_stream.newLine(); //send newline out_stream.flush(); } else if (prot=='f') { System.err.println("ERROR: protocol 'f' not yet implemented"); } else { System.err.println("ERROR: protocol must be 'p' or 'f'"); } } // // read from Linda using default protocol // returning a string // private String from_linda() throws IOException { return(from_linda(protocol)); //use default protocol } // // read from Linda using specified protocol // returning a string // private String from_linda(char prot) throws IOException { if (in_stream==null) { System.err.println("ERROR: input stream not opened"); throw new IOException("fail reading from Linda"); } if (prot=='p') { String s=in_stream.readLine(); //string read from stream if (s==null) return(null); return(s.substring(0,s.length()-1)); //remove the last period } else { System.err.println("ERROR: protocol 'f' not yet implemented"); return(null); } } // // read from Linda using default protocol // returning a reply in String & a status in char // private ReplyWithCode from_linda_with_code() throws IOException { return(from_linda_with_code(protocol)); //use default protocol } // // read from Linda with a specified protocol // returning a string & a char code // private ReplyWithCode from_linda_with_code(char prot) throws IOException { if (in_stream==null) { System.err.println("ERROR: input stream not opened"); throw new IOException("fail reading from Linda"); } if (prot=='p') { ReplyWithCode answer=new ReplyWithCode(); String s; char c; c=(char)in_stream.read(); //read char from stream s=in_stream.readLine(); //read string from stream answer.reply=s.substring(0,s.length()-1); answer.code=c; return(answer); } else { System.err.println("ERROR: protocol 'f' not yet implemented"); return(null); } } // // 'in' an item from Linda // public String in(String template) throws IOException, InterruptedIOException { socket.setSoTimeout(0); //turn off socket timeout for blocking 'in' to_linda('i',template); //send Linda the code 'i' & item template return(from_linda()); } // // 'in' an item with multiple templates // public String in(String[] templates) throws IOException, InterruptedIOException { socket.setSoTimeout(0); //turn off socket timeout for blocking 'in' to_linda('I',templates); return(from_linda()); } // // 'in' without blocking // public String in_noblock(String template,int this_timeout) throws IOException { String answer; to_linda('i',template); //it is still an "in" try { socket.setSoTimeout(this_timeout); //turn on socket timeout detection answer=from_linda(); //read from Linda server } catch (InterruptedIOException e) { disconnect(); //close connectioin connect(); //and re-connect return(null); //return null } socket.setSoTimeout(0); //turn off timeout return(answer); //return the reply string } public String in_noblock(String template) throws IOException { ReplyWithCode answer; to_linda('j',template); try { socket.setSoTimeout(timeout); //turn on socket timeout detection answer=from_linda_with_code(); //read from Linda server } catch (InterruptedIOException e) { socket.setSoTimeout(0); //turn off timeout return(null); //if timeout, return null } socket.setSoTimeout(0); //turn off timeout if (answer.code=='s') //if code is 's' for success { return(answer.reply); //return the reply string } return(null); //otherwise, return null for failure } // // 'rd' gets an item without removing it // public String rd(String template) throws IOException, InterruptedIOException { socket.setSoTimeout(0); //turn off socket timeout to_linda('r',template); //send the command code 'r' & template return(from_linda()); } // // 'rd' with multiple templates // public String rd(String[] templates) throws IOException, InterruptedIOException { socket.setSoTimeout(0); //turn off socket timeout to_linda('R',templates); //set command code 'R' & templates return(from_linda()); //get answer from Linda } // // 'rd' without blocking with timeout value specified // public String rd_noblock(String template,int this_timeout) throws IOException { String answer; to_linda('r',template); //it is still an "rd" try { socket.setSoTimeout(this_timeout); //turn on socket timeout detection answer=from_linda(); //read from Linda server } catch (InterruptedIOException e) { disconnect(); //close connectioin connect(); //and re-connect return(null); //return null } socket.setSoTimeout(0); //turn off timeout return(answer); //return the reply string } // // rd without blocking // public String rd_noblock(String template) throws IOException { ReplyWithCode answer; to_linda('s',template); try { socket.setSoTimeout(timeout); //turn on socket timeout detection answer=from_linda_with_code(); //read from Linda server } catch (InterruptedIOException e) { socket.setSoTimeout(0); //turn off timeout return(null); //if timeout, return null } socket.setSoTimeout(0); //turn off timeout if (answer.code=='s') //if code is 's' for success { return(answer.reply); //return the reply string } return(null); //otherwise, return null for failure } // // 'out' an item to the Linda server // public void out(String item) throws IOException { to_linda('o',item); //send item with the code 'o' } } class ReplyWithCode { String reply; char code; public void ReplyWithCode() { reply=null; code=' '; } public void ReplyWithCode(String s,char c) { reply=new String(s); code=c; } }