Stream Socket & multithreading

Hi,
I want the server in a stream based client - server program to be multithreaded in this way:
A thread is for reading purpose only and runs continuously as a listner for incoming messages. And an other thread processes the messages.
Is this possible (i tried to do it but this does not work)? Is there any example online?
Thank you

For normal sockets you need a thread for each socket. That thread can insert a message into a queue. And then another thread (only one) extracts the message and processes it.
If you really only want two threads and there will be more than one client then you will have to use nio.

Similar Messages

  • Facing error in creating ObjectInput/output stream socket

    hi I am Jatandar and i am implemeint client server program which will be using object Input/Output stream to pass data through sockets . The problem is the i m getting error when the cleint connects to the server here is the server and client code , YOur help will be appreciated
    Inventory class with serializable has been implemented
    public class Client
    public static void main( String [] args )//throws IOException
    Inventory invt[];
    try
    Socket serv = new Socket( "localhost", 8000 );
    // connect to server at port 8000
              ObjectInputStream ois ;     
    ois= new ObjectInputStream(serv.getInputStream());
    invt=(Inventory[]) ois.readObject() ;
    System.out.println(invt[0]);
    catch(IOException e )
    System.out.println(" no server Found \n");
    catch(Exception e)
    System.out.println(e);
    public class A3Server
         public static void main(String arg[] ) throws IOException
              //create a Server Socet
              ServerSocket ss= new ServerSocket(8000) ;
              ObjectOutputStream oos;
              //create a clent Socker that will listen for connection
              //listen for the connection from client
              BufferedReader br=null;
              FileReader fr=null;
              LinkedList ll=new LinkedList();
              StringTokenizer stkr;
              int i=0;
              Inventory inv=new Inventory();
              Inventory invt[];
              String t[]=new String[5];
              boolean choice=true;
              String temp="",temp2;
    // i am reading a text which contain data
    //that data is stored in invt []
    //that array is transfered to clien t when it is connected
         Socket toClient= ss.accept();
    oos = new ObjectOutputStream(toClient.getOutputStream());
    oos.writeObject(invt );
         oos.close();     
              }// end of main fucniton
         }//end of Server class
    DETAIL OF ERROR
    error in natived socket write method

    hi I am Jatandar and i am implemeint client server program which will be using object Input/Output stream to pass data through sockets . The problem is the i m getting error when the cleint connects to the server here is the server and client code , YOur help will be appreciated
    Inventory class with serializable has been implemented
    public class Client
    public static void main( String [] args )//throws IOException
    Inventory invt[];
    try
    Socket serv = new Socket( "localhost", 8000 );
    // connect to server at port 8000
              ObjectInputStream ois ;     
    ois= new ObjectInputStream(serv.getInputStream());
    invt=(Inventory[]) ois.readObject() ;
    System.out.println(invt[0]);
    catch(IOException e )
    System.out.println(" no server Found \n");
    catch(Exception e)
    System.out.println(e);
    public class A3Server
         public static void main(String arg[] ) throws IOException
              //create a Server Socet
              ServerSocket ss= new ServerSocket(8000) ;
              ObjectOutputStream oos;
              //create a clent Socker that will listen for connection
              //listen for the connection from client
              BufferedReader br=null;
              FileReader fr=null;
              LinkedList ll=new LinkedList();
              StringTokenizer stkr;
              int i=0;
              Inventory inv=new Inventory();
              Inventory invt[];
              String t[]=new String[5];
              boolean choice=true;
              String temp="",temp2;
    // i am reading a text which contain data
    //that data is stored in invt []
    //that array is transfered to clien t when it is connected
         Socket toClient= ss.accept();
    oos = new ObjectOutputStream(toClient.getOutputStream());
    oos.writeObject(invt );
         oos.close();     
              }// end of main fucniton
         }//end of Server class
    DETAIL OF ERROR
    error in natived socket write method

  • Closing streams, sockets, etc. upon abrupt end of program..?

    I'm trying to write a server that communicates with multiple clients that may come and go at random. Crossing that bridge when I get to it, but due to this need to constantly be making these sockets and breaking the links.. I can't be sure that, if a user closes my frame without using my supplied "Quit" button (which first calls a close method which closes any open sockets and IO streams), all those streams will be closed if the program is run again.
    I've experimented with it, and if I close the window I have open using the X, or alt+f4, or something to that effect (Using windows, which I suppose is evident now.), I still have a process running, and it's still doing stuff, which I can see by my desktop flickering every time the client tells me that it can't detect a server, or visa versa.
    Is there a method that is inherited by or included in the JFrame class that ensures when it mysteriously disappears, the method will be called first? This is a huge pain in the butt. Thanks.

    WindowListener ???

  • NS Stream Socket SSL Error Domain Error -9844

    The subject is the error I get when trying to check my work email via the iphone. I copied the settings (which included changing the ports for both incoming and outgoing mail under the advanced settings) directly from my outlook.
    Any thoughts about what this means?

    Hi Ram,
    Seems to be related to the X509v3 key usage of the certificate. How did you configure the server certificate?
    There is quite a lot of info available about this problem if you search for the keyword SEC_ERROR_INADEQUATE_KEY_USAGE
    Hope this helps
    -Sylvain

  • Parsing XML from Socket input stream

    I create a sax parser to which I send the InputStream from the socket
    But my HandlerBase never gets the events. I get startDocument
    but that is it, I never get any other event.
    The code I have works just like expected when I make the InputStream
    come from a file. The only differeence I see is that when I file is used the
    InputStream is fully consumed while with the socket the InputStream
    is kept open (I MUST KEEP THE SOCKET OPEN ALL THE TIME). If the parser
    does not generate the events unless the InputStream is fully consumed,
    isn't that against the whole idea of SAX (sax event driven) .
    Has anyone been succesfull parsing XML from the InputStream of a socket?
    if yes how?
    I am using JAXP 1.0.1 but I can upgrade to JAXP 1.1.0
    which uses SAX 2.0
    Does anybody know if my needs can be met by JAXP 1.1.0?
    Thanks

    I did the same with client/server model.
    I have client program with SAX parser. Please try if you can make the server side. I was be able to write the program with help from this forum. Please search to see if you can get the forum from which I got help for this program.
    // JAXP packages
    import javax.xml.parsers.*;
    import org.xml.sax.*;
    import org.xml.sax.helpers.*;
    // JAVA packages
    import java.util.*;
    import java.io.*;
    import java.net.*;
    public class XMLSocketClient {
    final private static int buffSize = 1024*10;
    final private static int PORTNUM = 8888;
         final private static int threadSleepValue = 1000;
    private static void usage() {
    System.err.println("Usage: XMLSocketClient [-v] serverAddr");
    System.err.println(" -v = validation");
    System.exit(1);
    public static void main(String[] args) {
    String address = null;
    boolean validation = false;
    Socket socket = null;
    InputStreamReader isr_socket = null;
    BufferedReader br_socket = null;
    CharArrayReader car = null;
    BufferedReader br_car = null;
    char[] charBuff = new char[buffSize];
    int in_buff = 0;
    * Parse arguments of command options
    for (int i = 0; i < args.length; i++) {
    if (args.equals("-v")) {
    validation = true;
    } else {
    address = args[i];
    // Must be last arg
    if (i != args.length - 1) {
    usage();
    // Initialize the socket and streams
    try {
    socket = new Socket(address, PORTNUM);
    isr_socket = new InputStreamReader(socket.getInputStream());
    br_socket = new BufferedReader(isr_socket, buffSize);
    catch (IOException e) {
    System.err.println("Exception: couldn't create stream socket "
    + e.getMessage());
    System.exit(1);
    * Check whether the buffer has input.
    try {
    while (br_socket.ready() != true) {
                   try {
                        Thread.currentThread().sleep(threadSleepValue);     
                   catch (InterruptedException ie) {
              System.err.println("Interrupted error for sleep: "+ ie.getMessage());
                   System.exit(1);
    catch (IOException e) {
    System.err.println("I/O error for in.read(): "+ e.getMessage());
    System.exit(1);
    try {
    in_buff = br_socket.read(charBuff, 0, buffSize);
    System.out.println("in_buff = " + in_buff);
    System.out.println("charBuff length: " + charBuff.length);
    if (in_buff != -1) {
    System.out.println("End of file");
    } catch (IOException e) {
    System.out.println("Exception: " + e.getMessage());
    System.exit(1);
    System.out.println("reading XML file:");
    StringBuffer display = new StringBuffer();
    display.append(charBuff, 0, in_buff);
    System.out.println(display.toString());
    * Create BufferedReader from the charBuff
    * in order to put into XML parser.
    car = new CharArrayReader(charBuff, 0, in_buff); // these two lines have to be here.
    br_car = new BufferedReader(car);
    * Create a JAXP SAXParserFactory and configure it
    * This section is standard handling of XML document by SAX XML parser.
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setValidating(validation);
    XMLReader xmlReader = null;
    try {
    // Create a JAXP SAXParser
    SAXParser saxParser = spf.newSAXParser();
    // Get the encapsulated SAX XMLReader
    xmlReader = saxParser.getXMLReader();
    } catch (Exception ex) {
    System.err.println(ex);
    System.exit(1);
    // Set the ContentHandler of the XMLReader
    xmlReader.setContentHandler(new MyXMLHandler());
    // Set an ErrorHandler before parsing
    xmlReader.setErrorHandler(new MyErrorHandler(System.err));
    try {
    * Tell the XMLReader to parse the XML document
    xmlReader.parse(new InputSource(br_car));
    } catch (SAXException se) {
    System.err.println(se.getMessage());
    System.exit(1);
    } catch (IOException ioe) {
    System.err.println(ioe);
    System.exit(1);
    * Clearance of i/o functions after parsing.
    try {
    br_socket.close();
    } catch (IOException e) {
    System.out.println("Exception: " + e.getMessage());
    try {
    socket.close();
    } catch (IOException e) {
    System.out.println("Exception: " + e.getMessage());
    try {
    br_car.close();
    } catch (IOException e) {
    System.out.println("Exception: " + e.getMessage());
    * The XML handler used by this program
    class MyXMLHandler extends DefaultHandler {
    // A Hashtable with tag names as keys and Integers as values
    private Hashtable tags;
    // Parser calls this once at the beginning of a document
    public void startDocument() throws SAXException {
    System.out.println("startDocument()");
    tags = new Hashtable();
    // Parser calls this for each element in a document
    public void startElement(String namespaceURI, String localName,
    String rawName, Attributes atts)
    throws SAXException
    String key = localName;
    Object value = tags.get(key);
    System.out.println("startElement()");
    System.out.println("namespaceURI: " + namespaceURI);
    System.out.println("localName: " + localName);
    System.out.println("rawName: " + rawName);
    if (value == null) {
    // Add a new entry
    tags.put(key, new Integer(1));
    } else {
    // Get the current count and increment it
    int count = ((Integer)value).intValue();
    count++;
    tags.put(key, new Integer(count));
    // Parser calls this once after parsing a document
    public void endDocument() throws SAXException {
    Enumeration e = tags.keys();
    System.out.println("endDocument()");
    while (e.hasMoreElements()) {
    String tag = (String)e.nextElement();
    int count = ((Integer)tags.get(tag)).intValue();
    System.out.println("Tag <" + tag + "> occurs " + count
    + " times");
    * Error handler of XML parser to report errors and warnings
    * This is standard handling.
    class MyErrorHandler implements ErrorHandler {
    /** Error handler output goes here */
    private PrintStream out;
    MyErrorHandler(PrintStream out) {
    this.out = out;
    * Returns a string describing parse exception details
    private String getParseExceptionInfo(SAXParseException spe) {
    String systemId = spe.getSystemId();
    if (systemId == null) {
    systemId = "null";
    String info = "URI=" + systemId +
    " Line=" + spe.getLineNumber() +
    ": " + spe.getMessage();
    return info;
    * The following methods are standard SAX ErrorHandler methods.
    * See SAX documentation for more info.
    public void warning(SAXParseException spe) throws SAXException {
    out.println("Warning: " + getParseExceptionInfo(spe));
    public void error(SAXParseException spe) throws SAXException {
    String message = "Error: " + getParseExceptionInfo(spe);
    throw new SAXException(message);
    public void fatalError(SAXParseException spe) throws SAXException {
    String message = "Fatal Error: " + getParseExceptionInfo(spe);
    throw new SAXException(message);

  • Open an input stream to a socket

    How many times I can open an input stream to a socket? If I create more than one an input stream to a socket, does this affect anything?
    Thanks.

    Generally low level classes do not have high level logic. Socket is a low level class, it's only logic is to connect you to something, and allow you to read and write to that thing (through the socket) using streams. Being able to connect multiple times or setting marks on your stream is a higher level of logic. Putting to much logic is low level classes tends to reduce re-useablility (making unmarkable streams markable as nothing to do with sockets and can be re-used upon any streams that do not support to be marked) and sometimes performances (having marks means having a buffer means having a potential big memory allocation in your Socket that you do not control).
    So in your case, since you are not really interested in re-connecting a socket, you should rather go for a wrapping InputStream that provides marking capabilities over the streams used by the socket class itself.
       Socket socket = getSocket();
       // this one does not support to be marked
       InputStream stream = socket.getInputStream();
       // but now it does :)
       stream = new BufferedInputStream( stream );

  • Send many files through a socket without closing Buffered Streams?

    Hi,
    I have an application that sends/receives files through a socket. To do this, on the receiver side I have a BufferedInputStream from the socket, and a BufferedOutputStream to the file on disk.
    On the sender side I have the same thing in reverse.
    As you know I can't close any stream, ever.. because that closes the underlying socket (this seems stupid..?)
    therefore, how can I tell the receiver that it has reached the end of a file?
    Can you show me any examples that send/receive more than one file without closing any streams/sockets?

    Hi,
    As you know I can't close any stream, ever.. because that closes the underlying socket (this seems stupid..?)Its not if you want to continuosly listen to the particular port.. like those of server, you need to use ServerSocket.
    for sending multiple files the sender(Socket) can request the file to server (ServerSocket). read the contents(file name) and then return the file over same connection, then close the connection.
    For next file you need to request again, put it in loop that will be better.
    A quick Google gives me this.
    Regards,
    Santosh.

  • Socket + GZip Stream + Object Stream problem

    Hello,
    I've been having a problem with my threaded networked application. I want to send GZipped Objects over a socket, but the ObjectInputStream constructor blocks. I understand that it is waiting for header information from the corresponding ObjectOutputStream. I am sure that the socket connection has been established, and the ObjectOutputStream is constructed before the ObjectInputStream on the other end. The header information never seems to get to the other end.
    If I remove the Gzip filter stream, everything works great. I'm thinking that the Gzip stream is buffering the 4 bytes of header info, waiting for more data before actually compressing anything. I've tried flushing everything, to no help. I've tried finish()ing the Gzip stream, but that means I can't send my object payload. I've checked the buffers of all the stream objects and see the Object Stream's header in its buffer, but never seems to get into the GZIPOutputStream's buffer.
    Has anyone successfully used Object Stream > GZIP Stream > Socket Stream before?
    I'm not interested in examples that use file streams, since I get the impression that Gzip works fine with those (and maybe even designed only for those, not for sockets).
    Thanks for any help.
    Dave C

    Thanks. I see what I'm doing differently now. I was trying to send multiple objects over the gzip stream, not 1 at a time, finish(), and construct a new Gzip and Object output stream.
    Seems to work with a ByteArrayOutput/InputStream, now to try with a socket..

  • Socket example using Java 5

    Last year I posted 4 programs that provided a simple client server using both stream sockets and NIO. I decided as an exercise in using Java 5 to port that code and try to use as many of the new features as possible. The following code is very long and does what all the previous example programs did. In replies do not repost the whole of this message.
    It provides a simple chat like client and server. The user can request either a stream connection or a NIO connection or provide one of their own.
    //========================== MsgSwitch.java ===========================//
    package pkwnet.msgswitch;
    import java.util.logging.Logger;
    import java.util.logging.Level;
    import java.util.logging.Handler;
    * main class for message switch
    * command line arguments are
    * -p port number for server
    * -s run server
    * -a server ip address including port for client
    * -i idle timer in seconds
    * -n use NIO
    * -c specify connection class
    public class MsgSwitch {
        static private int errors = 0;
        static private String address = "127.0.0.1:6060";
        static private String connectionClass = "pkwnet.msgswitch.StreamConnection";
        static public void main(String [] args) {
            int port = 6060;
            int idleTime = 600;
            boolean server = false;
            boolean nio = false;
            Logger logger = Logger.getLogger("msgswitch");
            for(String arg : args) {
                if(arg.startsWith("-a")) {
                    address = arg.substring(2);
                } else if(arg.startsWith("-p")) {
                    port = argToInt(arg);
                    server = true;
                } else if(arg.startsWith("-i")) {
                    idleTime = argToInt(arg);
                } else if (arg.startsWith("-s")) {
                    server = true;
                } else if (arg.startsWith("-c")) {
                    connectionClass = arg.substring(2);
                } else if (arg.startsWith("-n")) {
                    connectionClass = "pkwnet.msgswitch.NIOConnection";
                } else {
                    String err = "unknown argument=" + arg;
                    logger.severe(err);
                    System.err.println(err);
                    errors++;
            if (errors == 0) {
                if (server) {
                    new Server().listen(port,idleTime, nio);
                } else {
                    new Client().start(address, nio);
            } else {
                fail(errors + " errors encountered", null);
        static private int argToInt(String arg) {
            int val = 0;
            try {
                val = Integer.parseInt(arg.substring(2));
            } catch (NumberFormatException e) {
                String err = "invalid argument format: " + arg;
                Logger.getLogger("msgswitch").severe(err);
                System.err.println(err);
                errors++;
            return val;
        static public void fail(String err, Throwable e) {
            String msg = "Operation terminated: " + err;
            Logger.getLogger("msgswitch").log(Level.SEVERE, msg, e);
            System.err.println(msg);
            System.exit(12);
        static public Connection getConnection() {
            Connection conn = null;
            try {
                conn = (Connection) Class.forName(connectionClass).newInstance();
            } catch (Exception e) {
                fail ("connection class error", e);
            return conn;
        static public void logCaller(Logger logger, Level level) {
            String text = "CALLED";
            if (logger.isLoggable(level)) {
                try {
                    throw new Exception("logging stack");
                } catch (Exception e) {
                    StackTraceElement [] st = e.getStackTrace();
                    if (st.length > 1) {
                        text += formatElement(st[1]);
                    if (st.length >2) {
                        text += formatElement(st[2]);
                logger.log(level, text);
        static private String formatElement(StackTraceElement ste) {
            return "\n    " + ste.getClassName() + "." + ste.getMethodName()
                + "(" + ste.getFileName() + ":" + ste.getLineNumber() + ")";
    //================= Client.java =============================================//
    package pkwnet.msgswitch;
    * a simple Swing chat GUI using Java 5 and sockets.
    * @author PKWooster
    * @version 1.0 August 31,2005
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.JTextArea;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JMenu;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JDialog;
    import javax.swing.SwingUtilities;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.BorderLayout;
    import static java.awt.BorderLayout.*;
    client GUI class
    public class Client extends JFrame implements ConnectionListener {
         // swing GUI components
         private JTextField userText = new JTextField(40);
         private JTextArea sessionLog = new JTextArea(24,40);
         private JTextField statusText = new JTextField(40);
         private JPanel outPanel = new JPanel();
         private JScrollPane sessionLogScroll = new JScrollPane(sessionLog);
         private JMenuBar menuBar = new JMenuBar();
         private JMenuItem startItem = new JMenuItem("Start");
         private JMenuItem hostItem = new JMenuItem("Host");
         private JMenuItem aboutItem = new JMenuItem("About");
         private JMenuItem abortItem = new JMenuItem("Abort");
         private JMenuItem exitItem = new JMenuItem("Exit");
         private JMenu fileMenu = new JMenu("File");
         private JMenu helpMenu = new JMenu("Help");
         private Container cp;
         private String address;
        private Connection connection;
        private boolean sendReady = false;
        private boolean nio = false;
         Client() {
        public void start(String address, boolean nio) {
            this.address = address;
            this.nio = nio;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    runClient();
        private void runClient() {   
            connection = MsgSwitch.getConnection();
            connection.addConnectionListener(this);
              buildMenu();
              cp = getContentPane();
              sessionLog.setEditable(false);
              outPanel.add(new JLabel("Send: "));
              outPanel.add(userText);
              // enter on userText causes transmit
              userText.addActionListener(new ActionListener(){
                   public void actionPerformed(ActionEvent evt){userTyped(evt);}
              cp.setLayout(new BorderLayout());
              cp.add(outPanel,NORTH);
              cp.add(sessionLogScroll,CENTER);
              cp.add(statusText,SOUTH);
              setStatus("Closed");
              addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent evt) {
                    mnuExit();
              pack();
            setVisible(true);
    * attempt to send the contents of the user text field
        private void userTyped(ActionEvent evt) {
            if (sendReady) {
                String txt = evt.getActionCommand()+"\n";
                userText.setText("");
                toSessionLog("> ", txt);
                sendReady = false;
                connection.send(txt);
    * append text to the session log
         private void toSessionLog(String prefix, String txt) {
              sessionLog.append(prefix + txt);
              sessionLog.setCaretPosition(sessionLog.getDocument().getLength() ); // force last line visible
    * build the standard menu bar
         private void buildMenu()
              JMenuItem item;
              // file menu
              startItem.addActionListener(new ActionListener()
              {public void actionPerformed(ActionEvent e){mnuStart();}});
              fileMenu.add(startItem);
              hostItem.addActionListener(new ActionListener()
              {public void actionPerformed(ActionEvent e){mnuHost();}});
              fileMenu.add(hostItem);
              exitItem.addActionListener(new ActionListener()
              {public void actionPerformed(ActionEvent e){mnuExit();}});
              fileMenu.add(exitItem);
              menuBar.add(fileMenu);
              helpMenu.add(aboutItem);
              aboutItem.addActionListener(new ActionListener()
              {public void actionPerformed(ActionEvent e){mnuAbout();}});
              menuBar.add(helpMenu);
              setJMenuBar(menuBar);
    * start and stop communications from start menu
         private void mnuStart() {
            if(connection.getState() ==  Connection.State.CLOSED) {
                connection.connect(address);
            } else {
                connection.disconnect();
    *  prompt user for host in form address:port
        private void mnuHost() {
              String txt = JOptionPane.showInputDialog("Enter host address:port", connection.getAddress());
              if (txt == null)return;
            address = txt;
         private void mnuAbout() {
              JDialog dialog = new JDialog(this, "About Client");
              JTextField text = new JTextField("Simple character client");
            dialog.getContentPane().add(text);
            dialog.pack();
            dialog.setVisible(true);
         // exit menu
         private void mnuExit() {
            exit();
        private void exit() {
              connection.disconnect();
              System.exit(0);
         private void setStatus(String st) {
            statusText.setText(st);
         private void setStatus(Connection.State state) {
            switch(state) {
                case OPENED:
                    startItem.setText("Stop");
                    setStatus("Connected to "+address);
                    break;
                case CLOSED:
                    startItem.setText("Start");
                    setStatus("Disconnected");
                    break;
                case OPENING:
                    setStatus("Connecting to "+address);
                    startItem.setText("Abort");
                    break;
                case CLOSING:
                    setStatus("Disconnecting from "+address);
                    startItem.setText("Abort");
                    break;
        public void stateChanged(final ConnectionEvent event) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    setStatus(event.getState());
        public void dataAvailable(final ConnectionEvent event) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    setStatus(event.getState());
                    String txt = event.getData();
                    if (txt == null) {
                        txt = "$null$";
                    toSessionLog("< ", txt + "\n");   
        public void sendAllowed(final ConnectionEvent event) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    setStatus(event.getState());
                    sendReady = true;
        public void accept(ConnectionEvent event) {
    //========================== Server.java ===============================//
    package pkwnet.msgswitch;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    * a simple message switch using stream based socket i/o
    * a very simple text message switching program
    * user commands start with $ and consist of blank seperated arguments
    * other lines sent by the user are forwarded
    * $on nickname targets
    *    sign on as nickname, sending to targets
    * $to targets
    *    change target list, reports current value
    * $list nicknames
    *    list status of specified nicknames
    * $list
    *    list all connected users
    * $off
    *    sign off
    * @author PKWooster
    * @version 1.0 September 1, 2005
    public class Server {
        private ConcurrentHashMap<String, User> perUser = new ConcurrentHashMap<String,User>();
        private Timer idleTimer;
        private Connection conn;
        public void listen(int port, final int idleTime, boolean nio) {
            idleTimer = new Timer();
            idleTimer.scheduleAtFixedRate(new TimerTask(){public void run(){oneSec();}},0,1000);
            conn = MsgSwitch.getConnection();
            conn.addConnectionListener(new ConnectionListener() {
                public void stateChanged(ConnectionEvent event) {
                public void dataAvailable(ConnectionEvent event) {
                public void sendAllowed(ConnectionEvent event) {
                public void accept(ConnectionEvent event) {
                    Connection uconn = event.getConnection();
                    new User(uconn, perUser, idleTime);
            conn.listen(port);
            idleTimer.cancel();
        private void oneSec() {
            Collection<User> uc = perUser.values();
            for(User u : uc) {
                u.oneSec();
    //================= User.java  ==============================================//
    package pkwnet.msgswitch;
    import java.io.*;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.logging.Logger;
    import java.util.logging.Level;
    * defines the processing for a message switch user
    * @author PKWooster
    * @version 1.0 June 15,2004
    public class User implements ConnectionListener {
        private ConcurrentHashMap<String, User> perUser;
        private String name;
        private String address;
        private boolean signedOn = false;
        private String[] targets;
        private AtomicInteger remainingTime;
        private int idleTime;
        Connection conn;
        Logger logger;
      * construct a user, link it to its connection and put it in the perUser table
        User(Connection conn, ConcurrentHashMap<String,User>p, int idle) {
            this.conn = conn;
            logger = Logger.getLogger("msgswitch.user");
            conn.addConnectionListener(this);
            address = conn.getAddress();
            logger.info("creating user " + address);
            perUser = p;
            idleTime = idle;
            remainingTime = new AtomicInteger(idleTime);
            rename(address);
            targets = new String[0];
    * process state changes
        public void stateChanged(ConnectionEvent event) {
            if(event.getState() == Connection.State.CLOSED) {
                close(false);
    * data is available, process commands and forward other data.
        public void dataAvailable(ConnectionEvent event) {
            String msg = event.getData();
            if (msg.startsWith("$")) {
                doCommand(msg);
            } else {
                forward(msg);
            remainingTime.set(idleTime);
    * do nothing for sendAllowed events
        public void sendAllowed(ConnectionEvent event) {
    * do nothing for accept events
        public void accept(ConnectionEvent event) {
    * called once per second by the server main thread.
        public void oneSec() {
            if(idleTime != 0 && 1 > remainingTime.decrementAndGet()) {
                close(true);
    * send a message
        private void send(String msg) {
            conn.send(msg);
            remainingTime.set(idleTime);
    * forward data messages to other users
    * @param txt the message to send
        private void forward(String txt) {
            txt = name+": "+txt + "\n";
            if(0 < targets.length) {
                for(String target :targets) {
                    User user = perUser.get(target);
                    if(user != null) {
                        user.send(txt);
            } else {
                for (User user : perUser.values()) {
                    if (user != this) {
                        user.send(txt);
    * execute command messages, commands start with a $
    * and contain arguments delimited by white space.
    * @param command the command string
        private void doCommand(String command) {
            boolean good = false;
            command = command.substring(1).trim();
            if(command.length() > 0) {
                String [] args = command.split("\\s+");
                if(args[0].equals("on")) {
                    good = signOn(args);
                } else if(args[0].equals("off")) {
                    good = signOff(args);
                } else if(args[0].equals("list")) {
                    good = listUsers(args);
                } else if(args[0].equals("to")) {
                    good = setTargets(args,1);
                } else if(args[0].equals("idle")) {
                    good = setIdle(args);
                if(!good) {
                    send("invalid command=" + command + "\n");
    * sign on command
        private boolean signOn(String [] args) {
            boolean good = false;
            if(args.length >1) {
                String nm = args[1];
                logger.info("signing on as: " + nm);
                if(rename(nm)) {
                    conn.setName(name);
                    send("Signed on as " + name + "\n");
                    signedOn = true;
                    good = true;
                    setTargets(args,2);
                } else {
                    send("name="+nm+" already signed on\n");
            return good;
    * set forwarding targets
        private boolean setTargets(String [] args, int start) {
            if(start < args.length) {
                targets = new String[args.length-start];
                System.arraycopy(args, start, targets, 0, targets.length);
            String str = "to=";
            for(String target : targets) {
                str += (target + " ");
            send(str+"\n");
            return true;
    * set idle timeout
        private boolean setIdle(String[] args) {
            try {
                idleTime = new Integer(args[1]).intValue();
                remainingTime.set(idleTime);
                send("idle time set to "+idleTime+"\r\n");
                return true;
            } catch(NumberFormatException exc) {
                return false;
    * sign off
        private boolean signOff(String [] args) {
            close(true);
            return true;
    * list connected users
        private boolean listUsers(String [] args) {
            TreeSet<String> allUsers = new TreeSet<String>(perUser.keySet());
            HashSet<String> t = new HashSet<String>(Arrays.asList(targets));
            LinkedList<String> users;
            String response = "On,Target,Nickname\n";
            if(args.length < 2) {
                users = new LinkedList<String>(allUsers);
            } else {
                users = new LinkedList<String>();
                for (int i = 1; i < args.length; i++) {
                    users.add(args);
    for(String username : users) {
    if(username.equals(name)) {
    response += "*,";
    } else {
    response += (allUsers.contains(username) ? "y," : "n,");
    response += (t.contains(username) ? "y," : "n,");
    response += (username + "\n");
    send(response);
    return true;
    * rename this user, first we attempt to add the new name then we remove
    * the old one. Both names will be registered for a short while.
    * @param newname the new name for this user
    * @return true if the rename was successful
    private boolean rename(String newname) {
    boolean b = false;
    logger.info("rename name="+name+" newname="+newname);
    if (name != null && name.equals(newname)) {
    b = true;
    } else if (null == perUser.putIfAbsent(newname, this)) {
    if (name != null) {
    perUser.remove(name);
    name = newname;
    b = true;
    return b;
    * delete from perUser and close our connection
    private void close(boolean disconnect) {
    logger.info("closing user "+name);
    perUser.remove(name);
    if (disconnect) {
    conn.disconnect();
    //====================== Connection.java ===============================//
    package pkwnet.msgswitch;
    import java.util.HashSet;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.logging.Logger;
    import java.util.logging.Level;
    public abstract class Connection {
    public enum State {CLOSED, OPENING, OPENED, CLOSING}
    private HashSet<ConnectionListener> listeners = new HashSet<ConnectionListener>();
    private State state = State.CLOSED;
    private String host = "127.0.0.1";
    private int port = 6060;
    private String name = "unconnected";
    public Connection() {
    public abstract void listen(int port);
    public abstract void connect(String address);
    public abstract void disconnect();
    public abstract void send(String message);
    public void addConnectionListener(ConnectionListener listener) {
    listeners.add(listener);
    public void removeConnectionListener(ConnectionListener listener) {
    listeners.remove(listener);
    protected void fireDataAvailable(String data) {
    for (ConnectionListener listener : listeners) {
    listener.dataAvailable(new ConnectionEvent(this, state, data));
    private void fireStateChanged() {
    for (ConnectionListener listener : listeners) {
    listener.stateChanged(new ConnectionEvent(this, state));
    protected void fireSendAllowed() {
    for (ConnectionListener listener : listeners) {
    listener.sendAllowed(new ConnectionEvent(this, state));
    protected void fireAccept(Connection conn) {
    for (ConnectionListener listener : listeners) {
    listener.accept(new ConnectionEvent(this, conn));
    protected void setState(State state) {
    if (this.state != state) {
    this.state = state;
    fireStateChanged();
    public State getState() {
    return state;
    protected void setAddress(String address) {
              int n = address.indexOf(':');
              String pt = null;
    setName(address);
    if(n == 0) {
                   host = "127.0.0.1";
                   pt = address.substring(1);
              else if(n < 0) {
                   host = address;
                   port = 5050;
              } else {
    host = address.substring(0,n);
                   pt = address.substring(n+1);
    if (pt != null) {
    try {
    port = Integer.parseInt(pt);
    } catch (NumberFormatException e) {
    port = -1;
    public String getName() {
    return name;
    public void setName(String value) {
    name = value;
    public String getAddress() {
    return host + ":" + port;
    public String getHost() {
    return host;
    public void setPort(int value) {
    port = value;
    public int getPort() {
    return port;
    //=================== ConnectionEvent.java ================================//
    package pkwnet.msgswitch;
    public class ConnectionEvent extends java.util.EventObject {
    private final String data;
    private final Connection.State state;
    private final Connection conn;
    public ConnectionEvent(Object source, Connection.State state, String data, Connection conn) {
    super(source);
    this.state = state;
    this.data = data;
    this.conn = conn;
    public ConnectionEvent(Object source, Connection.State state, String data) {
    this(source, state, data, null);
    public ConnectionEvent(Object source, Connection.State state) {
    this(source, state, null, null);
    public ConnectionEvent(Object source, Connection conn) {
    this(source, conn.getState(), null, conn);
    public Connection.State getState() {
    return state;
    public String getData() {
    return data;
    public Connection getConnection() {
    return conn;
    //============================ ConnectionListener.java ===================//
    package pkwnet.msgswitch;
    public interface ConnectionListener extends java.util.EventListener {
    public void stateChanged(ConnectionEvent event);
    public void dataAvailable(ConnectionEvent event);
    public void sendAllowed(ConnectionEvent event);
    public void accept(ConnectionEvent event);
    //============================ StreamConnection.java ===================//
    package pkwnet.msgswitch;
    import java.net.Socket;
    import java.net.ServerSocket;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.IOException;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.logging.Logger;
    import java.util.logging.Level;
    * provides stream socket i/o of character strings
    * @author PKWooster
    * @version 1.0 September 1, 2005
    public class StreamConnection extends Connection {
    private Socket sock;
    private BufferedReader in;
    private BufferedWriter out;
    private Thread recvThread = null;
    private Thread sendThread = null;
    protected LinkedBlockingQueue<String> sendQ;
    Logger logger;
    public StreamConnection() {
    super();
    logger = Logger.getLogger("msgswitch.stream");
    sendQ = new LinkedBlockingQueue<String>();
    * open a socket and start i/o threads
    public void connect(String ipAddress) {
    setAddress(ipAddress);
    try {
    sock = new Socket(getHost(), getPort());
    connect(sock);
    } catch (IOException e) {
    logger.log(Level.SEVERE, "Connection failed to=" + ipAddress, e);
    private void connect(Socket sock) {
    this.sock = sock;
    String ipAddress = getAddress();
    try {
    in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
    out = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
    recvThread = new Thread(new Runnable() {
    public void run() {
    doRecv();
    },"Recv." + getName());
    sendThread = new Thread(new Runnable() {
    public void run() {
    doSend();
    },"Send."+getName());
    sendThread.start();
    recvThread.start();
    setState(State.OPENED);
    } catch(IOException e) {
    logger.log(Level.SEVERE, "Connection failed to="+ipAddress, e);
    public void listen(int port) {       
    StreamConnection sconn;
    setPort(port);
    try {
    ServerSocket ss = new ServerSocket(port);
    while(true) {
    Socket us = ss.accept();
    sconn = new StreamConnection();
    String ipAddress = us.getInetAddress() + ":" + us.getPort();
    sconn.setAddress(ipAddress);
    sconn.connect(us);
    fireAccept(sconn);
    } catch(Exception e) {
    logger.log(Level.SEVERE, "listen failed", e);
    * close the socket connection
    public void disconnect() {
    logger.fine("disconnect sock=" + sock + " state="+ getState());
    if(getState() == State.OPENED) {
    setState(State.CLOSING);
    try {
    sock.shutdownOutput();
    } catch(IOException ie) {
    logger.log(Level.SEVERE, "showdown failed", ie);
    } else if(getState() != State.CLOSED) {
    try {
    sock.close();
    } catch(Exception e) {
    logger.log(Level.SEVERE, "close failed", e);
    if (sendThread.isAlive()) {
    sendThread.interrupt();
    sendQ.clear();
    setState(State.CLOSED);
    public void send(String message) {
    if (getState() == State.OPENED) {
    try {
    sendQ.put(message);
    } catch(InterruptedException e) {
    logger.log(Level.SEVERE, "sendQ put interrupted", e);
    setState(State.CLOSING);
    disconnect();
    * sets the public name of this connection
    public void setName(String name) {
    super.setName(name);
    if (sendThread != null) {
    try {
    recvThread.setName("recv." + name);
    sendThread.setName("send." + name);
    } catch(Exception e) {
    logger.log(Level.SEVERE, "nameing threads failed", e);
    * the main loop for the send thread
    private void doSend() {
    String msg;
    boolean running = true;
    while (running) {
    if (sendQ.size() == 0) {
    fireSendAllowed();
    try {
    msg = sendQ.take();
    out.write(msg);
    out.flush();
    } catch(Exception e) {
    if (getState() == State.OPENED) {
    logger.log(Level.SEVERE, "write failed", e);
    setState(State.CLOSING);
    disconnect();
    running = false;
    * the main loop for the receive thread
    private void doRecv() {
    String inbuf;
    while (getState() == State.OPENED) {
    try {
    inbuf = in.readLine();
    } catch(Exception e) {
    if (getState() == State.OPENED) {
    logger.log(Level.SEVERE, "readline failed", e);
    inbuf = null;
    if(inbuf == null) {
    logger.fine("null received on: " + getAdd

    Here are three of them:
    NIO server
    NIO client
    Multithreaded server
    The stream based client example seems to have been deleted, probably lost in the troll wars. I also posted a new Simple multithreaded server that uses the same protocol. As the client is missing, I'll repost it.

  • Socket problems when using pthreads

    When using pthreads, any calls to accept inside a thread other than main returns no remote address. While I don't believe this a POSIX standards violation, it is still somewhat inconvenient as it means main must be the only thread accepting connections if a log of remote hosts is to be maintained.
    If anyone has a solution to this problem please email me with a fix.
    Thanks.

    Hi,
    I have a Multithreaded application with Stream Socket.After Calling listen,the socket state is BOUND.What is mean by BOUND? How I can change this state to Listen?The server is not accepting the connection?
    I am looking forward some help regard with this issue.If you know solutions please mail me.[[email protected]]

  • How can i create a socket connection through an http proxy

    i'm trying to make a socket connection send an email - i have code that works when you don't have to go through a proxy server but i can't make it pass the proxy server.
    import java.net.*;
    import java.io.*;
    import java.util.*;
    public class Mail
    public String to_address = "[email protected]";
    public String from_address = "[email protected]";
    public String sendSub = "HeHeHe";
    public String sendBody = "hehehe - it worked";
    // This is created to allow data to be read in by the keyboard.
    BufferedReader in = new BufferedReader(
    new InputStreamReader(System.in));
         private void Mail(String to_address, // recipient's addresses
    String from_address, // sender's address
    String sendSub, // subject
    String sendBody) // Message
                   throws IOException, ProtocolException,      UnknownHostException {
         Socket socket;                // creates a Socket named socket
         PrintStream out;               // stream to write to socket
         String host = "imap.btopenworld.com";          // identification of the mail server host
    // creates a new socket for connection to the mail server
    // as well as two variables for the read and write streams
         socket = new Socket(host, 25); // opens socket to host on port 25 (SMTP port)
         out = new PrintStream(socket.getOutputStream());
    // read the initial message
         in.readLine();
    // Dialog with the mail server
    // send HELO to SMTP server HELO command is given by a connecting SMTP host
         out.println( "HELO " + host );
         out.flush() ;
         in.readLine();
    // Once we are connected to the mail server we start sending the email...
    // send "from"
         out.println( "MAIL FROM: " + from_address );
         out.flush() ;
         in.readLine();
    // send "to"
         out.println( "RCPT TO: " + to_address );
         out.flush() ;
         in.readLine();
    // prepare the mailserver to receive the data
         out.println( "DATA" );
         out.flush() ;
         in.readLine();
    // Send actual email
         out.println("From: " + from_address);
         out.println("To: " + to_address);
         out.println( "Subject: " + sendSub + "\n" );
         out.flush() ;
         out.println("");
         out.println( sendBody ) ;
         out.println(".") ; // standard to determine end-of-body
         out.flush() ;
         in.readLine();
    //Quit and closes socket
         out.println("QUIT");
         out.flush();
         in.close() ;
         socket.close() ;
         return ;
    public static void main (String [] args) throws IOException
    Mail themail = new Mail();
    }

    i've tried that but it doesn't seem to do nething - this is how i implemented it...
    import java.net.*;
    import java.io.*;
    import java.util.*;
    public class Mail
    public String to_address = "[email protected]";
    public String from_address = "[email protected]";
    public String sendSub = "HeHeHe";
    public String sendBody = "hehehe - it worked";
    // This is created to allow data to be read in by the keyboard.
    BufferedReader in = new BufferedReader(
    new InputStreamReader(System.in));
         private void Mail(String to_address, // recipient's addresses
    String from_address, // sender's address
    String sendSub, // subject
    String sendBody) // Message
                   throws IOException, ProtocolException,      UnknownHostException {
         Socket socket;                // creates a Socket named socket
         PrintStream out;               // stream to write to socket
         String host = "imap.btopenworld.com";          // identification of the mail server host
    // creates a new socket for connection to the mail server
    // as well as two variables for the read and write streams
         socket = new Socket(host, 25); // opens socket to host on port 25 (SMTP port)
         out = new PrintStream(socket.getOutputStream());
    // read the initial message
         in.readLine();
    System.getProperties().put( "proxySet", "true" );
              System.getProperties().put( "proxyHost", "144.124.16.28" );
              System.getProperties().put( "proxyPort", "8080" );
    // Dialog with the mail server
    // send HELO to SMTP server HELO command is given by a connecting SMTP host
         out.println( "HELO " + host );
         out.flush() ;
         in.readLine();
    // Once we are connected to the mail server we start sending the email...
    // send "from"
         out.println( "MAIL FROM: " + from_address );
         out.flush() ;
         in.readLine();
    // send "to"
         out.println( "RCPT TO: " + to_address );
         out.flush() ;
         in.readLine();
    // prepare the mailserver to receive the data
         out.println( "DATA" );
         out.flush() ;
         in.readLine();
    // Send actual email
         out.println("From: " + from_address);
         out.println("To: " + to_address);
         out.println( "Subject: " + sendSub + "\n" );
         out.flush() ;
         out.println("");
         out.println( sendBody ) ;
         out.println(".") ; // standard to determine end-of-body
         out.flush() ;
         in.readLine();
    //Quit and closes socket
         out.println("QUIT");
         out.flush();
         in.close() ;
         socket.close() ;
         return ;
    public static void main (String [] args) throws IOException
    Mail themail = new Mail();
    }

  • Socket read() call returning before timeout.

    I have a couple of applications which use the following basic socket reading approach:
    Socket socket = new Socket("192.168.0.1", 54321);
    socket.setSoTimeout (5000);
    InputStream stream = socket.getInputStream();
    byte[] data = new byte[232];
    boolean done = false;
    while (!done) {
        int res= stream.read(data);
        if (res < data.length) {
            System.err.println ("Error reading packet data - not enough data received: "+ res);
        // process and output the data
    try { stream.close(); } catch (Exception e) {}
    try { socket.close(); } catch (Exception e) {}The problem I am having is that sometimes read(byte[]) returns a before the full array's worth of data has been read, and before a timeout has occurred. I never get a SocketTimeoutException, but I do get my debugging output. I have recorded the network traffic with a packet sniffer (Wireshark), and what I am seeing is that in the instances where the read returns prematurely, it stops at the end of a TCP packet. The rest of the data is in another packet that arrives shortly afterwords (~1.5 ms or less).
    I know that with normal (file) input streams, read can return whenever it wants regardless of how many bytes were read, however I was under the impression that network streams are supposed to block until all the data arrives (or a timeout occurs, if set). Is this incorrect?

    djpeaco wrote:
    I know that with normal (file) input streams, read can return whenever it wants regardless of how many bytes were readThat's correct and that's exactly the reason you see the behavior you see.
    however I was under the impression that network streams are supposed to block until all the data arrives (or a timeout occurs, if set).Why? Why do you think that network streams behave differently in this regard?
    Why shouldn't it give you the data as soon as it's available, when every other stream works this way?
    Is this incorrect?Yes, you must assume that the streams of a socket follow the general InputStream/OutputStream contract and that includes possibly returning from read() before the full array is filled.

  • Datagram socket

    Can I have a datagram socket server receive messages from a stream socket client. Thanks,

    No, and you are in the wrong forum. Moving this to the Networking forum.

  • Socket connections on LAN?

    I am designing a java application which will have 100 clients and a database server over LAN. There is no application server, only core java is used to write the programming logic. Now, to read, update or write anything to the database a bare socket connection will be made by the client to the server over LAN. Please tell me is it safe to perform this kind of communication? Will the network connection sustain for a long time or there are many chances that it may break easily? In no case will I be able to use an application server. Can I design such an application that communicates through bare sockets with no protection as such?

    If you use stream sockets your connection will survive for long periods of time. I have an application that connects to a mainframe by sockets and to Oracle using OCI (which uses sockets) that stays up for a week at a time, only stopping when the mainframe goes down for weekly maintenance. It recovers when the mainframe restarts by attempting to reconnect once a minute.
    This said, you still should deal with the inevitable situation where the connection is lost due to network problems or aproblemon your server.

  • Closing Sockets

    Hi all,
    Im having a big problem with the closing of sockets.
    I have a simple program which handles the sending / receiving and monitoring of HTTP traffic.
    My program has a 'sender' part which opens a socket, writes a request (using the socket output stream), reads the response (using the socket input stream, until read() == -1 ) and then closes the streams and socket.
    The 'receiver' part simply receives socket connections, reads the content (until read() == -1), writes a response, and then closes the streams and socket.
    The monitor part is a simple 'tunnel'. For each received socket connection, a connection is made to a server.
    Two threads then operate like this:
    T1) While read from client != -1, write to server
    T2) While read from server != -1, write to client
    Seems simple enough, and sort of works.
    The problem I have is cleanly closing all sockets without screwing up either the tunnel or a client.
    I try not to close the streams / sockets at the 'logical' times, but for some reason any combination I try results in Socket Closed exceptions during a read in either the tunnel or the client.
    There is a fair amount of code - so I dont expect anyone to wade thru it to find the problem, but Im just wondering if anyone has:
    1) Had similar problems and found a solution
    2) Can point me in the direction for more details on the mechanics and implications of closing socket streams
    The java docs seem very sketchy on this subject!!
    Thanks for your help!

    Thanks for the response (2 dukes for the fast reply - plenty more available on this one though!)....
    Does this mean that there is no 'clean' way to accomplish the transfer task?
    I think both examples will work, but I have a couple of issues:
    This exception is quite normal and indicates that another thread abruptly forced your socket closed or you tried to read or write after closing it yourself. You must catch it.The problem I have with this is that under these circumstances, it is a 'SocketException' which is thrown. The API says that this is thrown if 'there is an error in the underlying protocol, such as a TCP error'. So to be sure I was dealing with the right problem, I'd have to start parsing the exception text looking for "Socket Closed".
    Im keener on option 2:
    providing signalling between your threads Sounds like this is what I need.... Again there is a catch though.
    See, the thread handling the client will be in a blocking read (it will have read everything from the client, and written it to the server. However, as the client socket isn't closed yet, it doesn't know its time to stop). So, Im back to using exceptions again (Im assuming I'd have to do an interrupt?).
    I thought I could get round this on the client side by closing the output stream after writing everything (would signify to the reader thread that all is done).
    This, however, just results in the socket getting closed (my ignorance of the underlying mechanics of sockets showing through here...).
    Further, I want my 'monitor' to work with all request / response based systems - so I cant write a termination sequence on the client side to indicate end of input.
    So - Im really stuck with using exceptions as flags then??

Maybe you are looking for