On 9/19/07, Trustin Lee <[EMAIL PROTECTED]> wrote:
> What we've found so far:
>
> 1) Non-broadcast packets are working fine.

I found an interesting behavior (probably JVM or Windows bug).  It
seems like it is who calls receive() or read() first that receives
non-broadcast packets.  It doesn't mean any socket can receive
non-broadcast packets but means only the *first* socket who called
receive() or read() will receive non-broadcast packets.

Therefore, the DatagramAcceptor thread is the only thread that
receives non-broadcast packets, and this is inefficient, though we can
live with it.

The worst thing is that we can't receive any packets if someone
created a connected socket on the same local port with different
remote port.  Please try the following datagram server:

-------- CODE BEGINS --------
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;

public class DatagramServer {
    private static final int SERVER_PORT = 1234;

    private static final int CLIENT_PORT = 5678;

    public static void main(String[] args) throws Exception {
        DatagramSocket cs2 = new DatagramSocket(null);
        cs2.setReuseAddress(true);
        cs2.setSoTimeout(100);
        cs2.bind(new InetSocketAddress(SERVER_PORT));
        cs2.connect(new InetSocketAddress(InetAddress.getLocalHost(),
                CLIENT_PORT + 1));

        DatagramSocket us1 = new DatagramSocket(null);
        us1.setReuseAddress(true);
        us1.setSoTimeout(100);
        us1.bind(new InetSocketAddress(SERVER_PORT));

        DatagramSocket cs1 = new DatagramSocket(null);
        cs1.setReuseAddress(true);
        cs1.setSoTimeout(100);
        cs1.bind(new InetSocketAddress(SERVER_PORT));
        cs1.connect(new InetSocketAddress(InetAddress.getLocalHost(),
                CLIENT_PORT));

        DatagramPacket p = new DatagramPacket(new byte[2048], 2048);
        for (;;) {
            try {
                cs1.receive(p);
                System.out.println("CS1: " + p.getSocketAddress() + ", "
                        + p.getLength());
            } catch (InterruptedIOException e) {
            }
            try {
                cs2.receive(p);
                System.out.println("CS2: " + p.getSocketAddress() + ", "
                        + p.getLength());
            } catch (InterruptedIOException e) {
            }
            try {
                us1.receive(p);
                System.out.println("US1: " + p.getSocketAddress() + ", "
                        + p.getLength());
            } catch (InterruptedIOException e) {
            }
        }
    }
}
-------- CODE ENDS --------

As you see, cs2 is created in prior to the other sockets.  The result
of the test looks like the following:

-------- RESULT BEGINS --------
US1: /192.168.0.3:5678, 3

CS1: /192.168.0.3:5678, 3

US1: /192.168.0.3:5678, 4

CS1: /192.168.0.3:5678, 4

-------- RESULT ENDS --------

Packet 1 and 2 are missing. :(

I also modified Main.java to send some packets to (CLIENT_PORT + 1) to
make sure CS2 is swallowing others' packets, and I got the following
result (Packets are sent 6 times, and packet #5 and 6 are broadcast
packets):

-------- RESULT BEGINS --------
CS2: /192.168.0.3:5679, 3

US1: /192.168.0.3:5678, 5

CS1: /192.168.0.3:5678, 5

CS2: /192.168.0.3:5679, 4

US1: /192.168.0.3:5678, 6

CS1: /192.168.0.3:5678, 6

-------- RESULT ENDS --------

In contrast, I got the following in Linux:

-------- RESULT BEGINS --------
CS1: /127.0.0.1:5678, 1
CS2: /127.0.0.1:5679, 3
CS1: /127.0.0.1:5678, 2
CS2: /127.0.0.1:5679, 4
US1: /127.0.0.1:5678, 5
US1: /127.0.0.1:5678, 6
-------- RESULT ENDS --------

IIUC, the test results we got means that the UDP/IP implementation of
Windows or Windows JVM is broken.  Did I guess correctly, or am I
missing something?

Even if it's a bug or not, it seems like the new datagram
implementation works OK with various operating systems with some
compromises.  I believe performance will improve definitely in Linux
and Solaris thanks to multi-thread support.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP Key ID: 0x0255ECA6

Reply via email to