JDK-6411513 : java.net.DatagramSocket.receive: packet isn't received
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,linux_suse_sles_9.3,solaris_7
  • CPU: x86,sparc
  • Submitted: 2006-04-11
  • Updated: 2019-09-23
  • Resolved: 2006-06-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u81Fixed 6 b89Fixed
Related Reports
Relates :  
Description
see test below

--------------------
import java.net.InetAddress;
import java.net.DatagramSocket;
import java.net.DatagramPacket;

public class Test2 {

    public static void main( String[] args ){
        try {

            InetAddress lh = InetAddress.getLocalHost();
            DatagramSocket s = new DatagramSocket(0, lh);
            try {
                DatagramSocket ss = new DatagramSocket(0, lh);
                try {
                    s.connect(ss.getLocalAddress(), ss.getLocalPort());
                    s.disconnect();

                    System.out.println( String.format( "DatagramSocket: (%s, %s), bound = %s, closed = %s, connected = %s", 
                                                            s.getLocalAddress(), s.getLocalPort(),
                                                            s.isBound(), s.isClosed(), s.isConnected() ) );
                    byte[] data = { 0, 1, 2 };
                    DatagramPacket p = new DatagramPacket(data, data.length, s.getLocalAddress(), s.getLocalPort());
                    s.setSoTimeout( 10000 );
                    s.send( p );
                    s.receive( p );
                    System.out.println( "OK" );
                } finally {
                    ss.close();
                }
            } finally {
                s.close();
            }
        } catch( Exception x ){
            x.printStackTrace( System.out );
        }
    }
}
--------------------
output:

DatagramSocket: (/10.16.106.217, 33411), bound = true, closed = false, connected = false
java.net.SocketTimeoutException: Receive timed out
        at java.net.PlainDatagramSocketImpl.receive0(Native Method)
        at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
        at java.net.DatagramSocket.receive(DatagramSocket.java:712)
        at Test2.main(Test2.java:25)
--------------------

This error appears only on linux OS.
It is interesting that changing order of DatagramSockets creation leads to normal test result.
JCK test
api/java_net/DatagramSocket/index.html#connect[DatagramSocket2016]
is failed

Comments
EVALUATION In 2.6.11 Linux kernel, when disconnect a UDP socket, the kernel will set local IP address to zero if the local address comes from a implicit bind: if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) inet_reset_saddr(sk); Same to the port number: if (!(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) { sk->sk_prot->unhash(sk); inet->sport = 0; }
01-06-2006

EVALUATION It is related to the disagreement of the local binding of a UDP socket during the disconnect process. If bind() being called explicitly, which is the case in current DatagramSocket implementation, Solaris remains local IP address unchanged. Linux sets the local address back to all zeros, even if bind() is called previously, but leaves the port number intact. So the successive send/recv will fail in Linux.
17-04-2006