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

(dc) DatagramSocket created by DatagramChannel does not provide sender info

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 1.4.2_02
    • Fix Version/s: 7
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Introduced In Version:
    • Resolved In Build:
      b100
    • CPU:
      sparc
    • OS:
      solaris_9
    • Verification:
      Verified

      Description

      During porting of an existing application from using a DatagramSocket to
      use NIO/DatagramChannel, the following problem was encoutered:

      Problem:

      When receiving messages directly from the socket created by DatagramSocket.open() the received DatagramPacket does not (seem to) contain information about the sender of the UDP message. When calling getAddress on a the DatagramPacket, this returns null. When calling getPort on the DatagramPacket, this returns -1. The DatagramPacket.getLength() returns
      the correct number of bytes in the UDP message, and the content of the
      UDP message is correct.

      What I did:

      In the application, I basically replaced the code for creating a socket:

        socket = new DatagramSocket(39300);

      with the following code:

        DatagramChannel channel = DatagramChannel.open();
        socket = channel.socket();
        socket.bind(new InetSocketAddress(39300));

      On this socket I receives messages by calling:

        packet = new DatagramPacket(new byte[32000], 32000);
        socket.receive(packet);

      I access information about the sender in this way:

        InetAddress address = packet.getAddress();
        int port = packet.getPort();

      If the socket is created as a DatagramSocket, I get the correct values from
      these two calls. If the socket is created using DatagramChannel.open +
      DatagramChannel.socket(), these two calls returns null and -1.

      The environment where this problem is produced is:

      Operating system:

      os136802@techra13:~/<6>hadb/comm> uname -a
      SunOS techra13 5.9 Generic_112233-07 sun4u sparc SUNW,Sun-Fire-V210

      Java platform:

      os136802@techra13:~/<6>hadb/comm> /usr/local/java/jdk/bin/java -version
      java version "1.4.2_02"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
      Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)

      I am enclosing two small programs for reproducing the problem.

      The first program receives UDP messages. It takes "1" or "2" as argument:

        1. the socket is created as a DatagramSocket.
        2. the socket is created using a DatagramChannel.

      This program should produce the following printout:

      os136802@techra13:~/<6>hadb/comm> /usr/local/java/jdk/bin/java -cp . RecvTest 1
      Creating socket directly
      Waiting for messages
      Got one message Wrom: TWFAOBUZXUWLSZLKBRNVWWCUFPE
      Got one message Wrom: GAUTFJMVRESKPNKMBIPBARHDMNN
      Got one message Wrom: SKVFVWRKJVZCMHVIBGDADRZFSQH

      When using a DatagramChannel for creating the socket, the printout is
      as follows:


      os136802@techra13:~/<6>hadb/comm> /usr/local/java/jdk/bin/java -cp . RecvTest 2
      Creating a datagram channel
      Waiting for messages
      Got one message Wrom: YUCDDJBLVLMHA
      Got one message Wrom: ALPTCXLYRWTQT

      Source code for program RecvTest.java:

      -------------------------------------------------------------------
      import java.lang.Thread;
      import java.io.*;
      import java.net.DatagramSocket;
      import java.net.DatagramPacket;
      import java.net.SocketException;
      import java.net.InetAddress;
      import java.net.InetSocketAddress;
      import java.nio.channels.DatagramChannel;


      public class RecvTest
      {
          public static void main (String[] args) {
              if (args.length != 1) {
                  System.out.println("Specify 1 or 2 as argument - exiting");
                  System.exit(1);
              }

              // Parse argument
              int mode = 0;
              try {
                  mode = Integer.parseInt(args[0].trim());
              } catch (Exception e) {
                  System.out.println("1 or 1 should be given as argument");
                  System.exit(1);
              }

              DatagramSocket socket = null;
              DatagramPacket packet = null;

              try {
                  if (mode != 2) {
                      /* Comment: creates the socket using the "old"
                         DatagramSocket class. This works as expected. */
                      System.out.println("Creating socket directly");
                      socket = new DatagramSocket(39300);
                  }
                  else {
                      System.out.println("Creating a datagram channel");
                      /* Comment: creates the socket by using the
                         DatagramChannel class and then getting access
                         of the socket by calling socket(). This socket
                         "refuses" to give out information about the
                         sender of an incomming UDP message. */
                      DatagramChannel channel = DatagramChannel.open();
                      socket = channel.socket();
                      socket.bind(new InetSocketAddress(39300));
                  }

                  packet = new DatagramPacket(new byte[32000], 32000);

              } catch (Exception e) {
                  System.out.println("Exception....");
                  System.exit(1);
              }

              System.out.println("Waiting for messages");

              try {
                  while (true) {
                      socket.receive(packet);

                      InetAddress address = packet.getAddress();
                      int port = packet.getPort();

                      if (address != null) {
                           System.out.println("Got one message Wrom: IPWI
                                              address.toString() + ":" + port +
                                              " len=" + packet.getLength());
                      }
                      else {
                           System.out.println("Got one message Wrom: GYOK
                                              "UNKNOWN" +
                                              " len=" + packet.getLength());
                      }
                  }
              } catch (IOException e) {
                  System.out.println("Exception....");
                  System.exit(1);
              }
          }

      }
      ------------------------------------------------------------------------

      The second programs sends UDP messages. To run it, change the name of
      the receiving machine.

      Source code for SendTest.java:

      ----------------------------------------------------------------------
      import java.lang.Thread;
      import java.io.*;
      import java.net.DatagramSocket;
      import java.net.DatagramPacket;
      import java.net.SocketException;
      import java.net.InetSocketAddress;


      public class SendTest
      {
          public static void main (String[] args) {
              // Message to send
              byte[] buf = new byte[4];
              InetSocketAddress addr = new InetSocketAddress("techra13", 39300);

              DatagramSocket socket = null;
              DatagramPacket packet = null;

              try {
                  socket = new DatagramSocket();

                  packet = new DatagramPacket(buf, buf.length,
                                              addr.getAddress(),
                                              addr.getPort());

              } catch (SocketException e) {
                  System.out.println("Exception....");
                  System.exit(1);
              }


              try {

                  while (true) {
                      System.out.println("Sending one message");
                      socket.send(packet);

                      try {

                          Thread.sleep(1000);
                      }
                      catch (InterruptedException e) {
                          System.out.print("Ignoring interrupted exception");
                      }

                  }
              } catch (IOException e) {
                  System.out.println("Exception....");
                  System.exit(1);
              }
          }

      }
      ------------------------------------------------------------------------

        Attachments

          Activity

            People

            • Assignee:
              alanb Alan Bateman
              Reporter:
              osandsta Olav Sandstå (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: