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

multiple calls of Socket.setTrafficClass() do not work

XMLWordPrintable

    • beta
    • x86
    • windows_2000, windows_xp

      FULL PRODUCT VERSION :
      java version "1.4.2_03"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
      Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows 2000 [Version 5.00.2195]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      registration key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\DisableUserTOSSetting
      is set as 0 (REG_DWORD)


      A DESCRIPTION OF THE PROBLEM :
      The first call of setTrafficClass(xx) works, but additional calls on the same socket (after writing some bytes) are not reliable.

      Even though getTrafficClass always returns the most recent tc value set by setTrafficClass, a network tool such as ethereal (http://ethereal.com) shows that the DSCP code is not changed correctly in the following case:
      1. No call of setTrafficClass(0) change the DSCP code of the TCP package.
      2. The third call of setTrafficClass(x), if tc is different from the second call, may not change the DSCP code; if tc is the same as in the second call, may change the DSCP code to another value.

      I used two simple Java programs as client and server, as attached at the end. I ran the server on a Linux (FC3) machine, and the client on the Intel/Win2K machine as described above. The client loops on setting the traffic class and then writing a block of bytes to the server. The server simply print it out. I ran ethereal on the client Win2K and captured the traffic with the filter "host xxx.xxx.xxx.xxx" where the server IP was used. The server is run by "java SimpleSocketServer <port>" on Linux, and run many client sessions like the following (start ethereal capture first, run the client, and stop capturing, and start the next session...):
      "...\j2sdk1.4.2_03\bin\java -cp . TOS <server> <port> 1460 34 46 34 46" where 1460 is the TCP packet (data) size so that each block written by Java code is actually transfered in a single TCP packet (otherwise, the problem will be more complicated).

      ==============TOS.java==========================
      import java.io.*;
      import java.net.*;
      import java.util.Arrays;

      public class TOS {

          public static void main(String[] args) throws Exception {
              if (args.length <4) {
                  System.err.println("Arguments: <host> <port> <size> <tc1> <tc2> ...");
                  return;
              }

              Socket socket = new Socket(args[0], Integer.parseInt(args[1]));
              socket.setTcpNoDelay(true);
              OutputStream os = socket.getOutputStream();
              byte[] bytes = new byte[Integer.parseInt(args[2])];
              for (int i=3; i<args.length; i++) {
                  int tc = Integer.parseInt(args[i]);
                  byte[] s = ("TC="+tc).getBytes();
                  Arrays.fill(bytes, (byte)0);
                  System.arraycopy(s, 0, bytes, 0, s.length);
                  socket.setTrafficClass(tc);
                  os.write(bytes);
                  System.out.println("Set Traffic class to "+tc+", got "+
                                     socket.getTrafficClass());
                  os.flush();
              }
              os.close();
              socket.close();
          }
      }
      ===========SimpleSocketServer.java===================
      import java.io.*;
      import java.net.*;

      public class SimpleSocketServer {
          static int nextId = 0;
          static class Worker extends Thread {
              private Socket socket;
              private int id;

              Worker(Socket socket) {
                  this.socket = socket;
                  id = nextId ++;
              }
              public void run() {
                  try {
                      InputStream is = socket.getInputStream();
                      byte[] buffer = new byte[1024];
                      while (true) {
                          int n = is.read(buffer);
                          if (n < 0) {
                              break;
                          }
                          System.out.println("Worker "+id+" read: "+n+" bytes");
                      }
                      is.close();
                      socket.close();
                  } catch (Exception x) {
                      x.printStackTrace();
                  }
              }
          }

          public static void main(String[] args) throws Exception {
              if (args.length != 1) {
                  System.err.println("Arguments: <port>");
                  return;
              }
              final ServerSocket server = new ServerSocket(Integer.parseInt(args[0]));
              System.out.println("Start server at "+server.getLocalSocketAddress());
              Runtime.getRuntime().addShutdownHook(new Thread() {
                      public void run() {
                          try {
                              server.close();
                          } catch (Exception x) {
                              x.printStackTrace();
                          }
                      }
                  });
              while (true) {
                  new Worker(server.accept()).start();
              }
          }
          

      }
      ==================================================

      This problem does not occur in Linux (Fedora Core 2)
      Thanks




      REPRODUCIBILITY :
      This bug can be reproduced always.

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround!
      ###@###.### 2005-1-18 14:33:22 GMT

            yuwangsunw Yujiang Wang (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: