According to one of my colleagues, it's not broken but the behavior is
just undefined.  So, reverted my work. :-(

Trustin

On 9/19/07, Trustin Lee <[EMAIL PROTECTED]> wrote:
> 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
>


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

Reply via email to