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>