Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4474929

JavaVM does not handle WSAENOBUFS (10055) optimally

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.1
    • core-libs
    • beta2
    • x86
    • windows_nt



      Name: bsC130419 Date: 06/26/2001


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

      Contact Information

      Computer Systems Research, Inc.
      Custom software specialists
      ###@###.###

      References

      * Platform is Win32 (Windows 9x or NT/2K)
      * MSDN article ID: Q201213
      * Winsock error code 10055, WSAENOBUFS
      * JDK 1.3.1 source code j2sdk1.3.1\src\win32
      \native\java\net\SocketOutputStream.c, function
      Java_java_net_SocketOutputStream_socketWrite

      Background

      I have been working on a project that requires client/server communications.
      Multiple clients connect to a server and send lots of data to the server as
      fast as possible. Intermittently, a client socket implemented with Java's
      Socket class will throw an exception during an OutputStream.write. Embedded in
      the exception's message string is code 10055. Under Win32, this error is
      WSAENOBUFS which means the TCP/IP stack has temporarily run out of buffer space
      and cannot complete the write. Microsoft has verified this as a bug in the
      WinSock TCP/IP stack (see the MSDN article listed in the References section
      above). This would be a recoverable error if not for the way the Java native
      code handles the error. The recovery would simply be to wait for the stack
      buffers to empty and try sending the same data again at a later time.

      The problem arises from the Win32 Java source code breaking a buffer passed to
      OutputStream.write into chunks (64K chunks if heap memory is available, 2K
      chunks on the stack if not). The suspect native code is listed in the
      References section above. Suppose I send a 128K buffer to OutputStream.write
      and the native code successfully transmits the first 64K chunk but the second
      64K chunk fails with error 10055. At this point, the native code throws a
      SocketException but does not tell the caller how many bytes were written before
      the error occurred. The caller does not know what part of the data stream
      should be retransmitted.

      Suggestion for Fix

      A fix for this easy to implement. In the native source code at line 114,
      instead of calling NET_ThrowCurrent, check the WSALastError code. If the code
      is 10055, throw an InterruptedIOException with bytesTransferred set to the
      variable loff. If the code is not 10055, handle it in the usual way by calling
      NET_ThrowCurrent. The Java application can then handle the
      InterruptedIOException and resume the transmission at the proper location.
      This solution works because the JVM_send at line 105 for blocking sockets under
      Win32 will either (1) send no data and return an error code or (2) send some or
      all of the data and return the number of bytes sent.

      Conclusion

      This bug in Win32 can be easily handled in the Java native code. Hopefully,
      this report is clear enough that a bug fix will be implemented soon.
      (Review ID: 124911)
      ======================================================================

            alanb Alan Bateman
            bstrathesunw Bill Strathearn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: