Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Apr 2000 18:54:35 -0400
From:      Taso Lyristis <taso@lyrisoft.com>
To:        freebsd-java@freebsd.org
Subject:   Socket bug and workaround example for FreeBSD JDK 1.2.2
Message-ID:  <39037F2B.8E010E21@lyrisoft.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------41B5B145C871309198599F2C
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello,

We have found what appears to be a bug in the (native) socket
implementation for JDK1.2.2 for FreeBSD.

The quick description of this bug is the following:  When implementing a
TCP/IP server, the native method java.net.SocketInputStream.socketRead()
throws a SocketException: Resource temporarily unavailable instead of
blocking until data becomes available.  This breaks any Java code that
depends on a blocking read from a socket's input stream.

I have attached 2 source files, Test1.java and Test2.java.  Test1
illustrates the bug, when running on FreeBSD, and Test2 illustrates a
partial workaround.  The example is of a simple non-threaded echo
server, where the server answers an incoming connection and just echos
back any data that it receives.

Here is the exception that Test1 throws.  This is throw immediately
after readLine() is called:
java.net.SocketException: Resource temporarily unavailable: Resource
temporarily unavailable
        at java.net.SocketInputStream.socketRead(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:90)
        at java.net.SocketInputStream.read(SocketInputStream.java:71)
        at java.io.InputStreamReader.fill(InputStreamReader.java:163)
        at java.io.InputStreamReader.read(InputStreamReader.java:239)
        at java.io.BufferedReader.fill(BufferedReader.java:137)
        at java.io.BufferedReader.readLine(BufferedReader.java:274)
        at java.io.BufferedReader.readLine(BufferedReader.java:329)
        at Test1.main(Test1.java:40)

Feel free to contact me if you need to.  I hope this helps in the
JDK1.2.2 on FreeBSD porting effort.

Best regards,
Taso Lyristis
--------------41B5B145C871309198599F2C
Content-Type: text/plain; charset=us-ascii;
 name="Test1.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Test1.java"

import java.io.*;
import java.net.*;

/**
 * A simple non-threaded "echo server".  This should illustrate the exception thrown
 * in the native method java.net.SocketInputStream.socketRead() on FreeBSD.
 * See Test2 for a work-around.
 *
 * @author Taso Lyristis (taso@lyrisoft.com) 2000-04-23
 */
public class Test1 {
    public static void main(String[] args) {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(Integer.parseInt(args[0]));
            System.err.println("Listening on port " + args[0]);
        }
        catch (IOException e) {
            e.printStackTrace();
            System.exit(2);
        }
        catch (Exception e) {
            System.err.println("usage: Test1 port");
            System.exit(1);
        }


        while (true) {
            Socket s = null;
            BufferedReader in = null;
            PrintWriter out = null;

            try {
                s = ss.accept();
                System.out.println("Connection from: " + s.getInetAddress());
                in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                out = new PrintWriter(s.getOutputStream());

                String line = null;
                while ((line = in.readLine()) != null) {
                    // simply echo each line back to the sender.
                    out.println(line);
                    out.flush();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("Closing connection to: " + s.getInetAddress());
                if (s != null) {
                    try {
                        s.close();
                    }
                    catch (IOException e) {}
                }
                in = null;
                out = null;
            }

        }
    }
}

--------------41B5B145C871309198599F2C
Content-Type: text/plain; charset=us-ascii;
 name="Test2.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Test2.java"

import java.io.*;
import java.net.*;

/**
 * A simple non-threaded "echo server".  This should illustrate the workaround to the
 * exception thrown in the native method java.net.SocketInputStream.socketRead() on FreeBSD.
 *
 * BUGS: We don't detect a connection getting closed.
 * 
 * @author Taso Lyristis (taso@lyrisoft.com) 2000-04-23
 */
public class Test2 {
    public static void main(String[] args) {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(Integer.parseInt(args[0]));
            System.err.println("Listening on port " + args[0]);
        }
        catch (IOException e) {
            e.printStackTrace();
            System.exit(2);
        }
        catch (Exception e) {
            System.err.println("usage: Test1 port");
            System.exit(1);
        }


        while (true) {
            Socket s = null;
            BufferedReader in = null;
            PrintWriter out = null;

            try {
                s = ss.accept();
                System.out.println("Connection from: " + s.getInetAddress());
                InputStream is = s.getInputStream();
                in = new BufferedReader(new InputStreamReader(is));
                out = new PrintWriter(s.getOutputStream());

                String line = null;
                do {
                    // The workaround is here:  While there is no data available, we sleep.
                    while (is.available() == 0) {
                        try {
                            Thread.sleep(25);
                        }
                        catch (InterruptedException e) {
                        }
                    }
                    line = in.readLine();
                    out.println(line);
                    out.flush();
                } while (line != null);
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("Closing connection to: " + s.getInetAddress());
                if (s != null) {
                    try {
                        s.close();
                    }
                    catch (IOException e) {}
                }
                in = null;
                out = null;
            }

        }
    }
}

--------------41B5B145C871309198599F2C--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-java" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?39037F2B.8E010E21>