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

Socket setSendBufferSize() does not work

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10 Pro
      Java 17

      A DESCRIPTION OF THE PROBLEM :
      Socket sendBufferSize() [https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/Socket.html?msclkid=4a181c0cceb311eca185e976544434c5#setSendBufferSize(int)] should limit the number of bytes sent to the server. Its value can decrease based on the receive buffer of the other end but should never increase beyond its own value

      If Server advertises an Receive Buffer Window [https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/Socket.html?msclkid=4a181c0cceb311eca185e976544434c5#setReceiveBufferSize(int)] of size 30 bytes and the client has an Send Buffer Window of only 10 bytes the client should only send 10 bytes of data with each packet as it is capable of only that much.

      But instead it ignores this setting and sends 30 bytes of data in each packet regardless i.e it adjusts according to the server settings

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Run an server socket on an separate process[JVM] and set its receiveBufferSize() before calling accept() to an value of 30

      2) Run the client on an separate process[JVM] and sets its sendBufferSize() to 10. In the client code and in the server code i have set this value 3 times but it didn't make a difference

      3) a) Open wire shark

         b) Select the capture option as Adapter for loop back traffic capture

         c) Set the display filter as tcp.dstport==2500 [packets going to port 2500]

         d) Run the capture process and wait

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      As the client socket is only capable of sending 10 bytes it should send 10 packets each of size 10 bytes
      ACTUAL -
      Client sends 4 packets 3 packets each of size 30 bytes and the last packet of size 10 bytes. Send Buffer Setting is ignored

      Wire shark Log[Data is sent from packet 9 onwards]

      No. Time Source Destination Protocol Length Info
      6 11.966141 192.168.1.2 192.168.1.2 TCP 56 60151 → 2500 [SYN] Seq=0 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM=1

      No. Time Source Destination Protocol Length Info
      8 11.966328 192.168.1.2 192.168.1.2 TCP 44 60151 → 2500 [ACK] Seq=1 Ack=1 Win=2619648 Len=0

      No. Time Source Destination Protocol Length Info
      9 11.967784 192.168.1.2 192.168.1.2 TCP 74 [TCP Window Full] 60151 → 2500 [ACK] Seq=1 Ack=1 Win=2619648 Len=30


      No. Time Source Destination Protocol Length Info
      11 11.967852 192.168.1.2 192.168.1.2 TCP 74 [TCP Window Full] 60151 → 2500 [ACK] Seq=31 Ack=1 Win=2619648 Len=30

      No. Time Source Destination Protocol Length Info
      13 11.967888 192.168.1.2 192.168.1.2 TCP 74 [TCP Window Full] 60151 → 2500 [ACK] Seq=61 Ack=1 Win=2619648 Len=30

      No. Time Source Destination Protocol Length Info
      15 11.967921 192.168.1.2 192.168.1.2 TCP 54 60151 → 2500 [PSH, ACK] Seq=91 Ack=1 Win=2619648 Len=10

      Upon checking the size of the send buffer on the client it prints 10 but it sends 30 bytes

      ---------- BEGIN SOURCE ----------
      Server. Run as a separate process[JVM]

      public static void main(String[] args)throws Exception
       {
        try(ServerSocket server=new ServerSocket())
        {
        //tells client able to receive only 30 bytes
         server.setReceiveBufferSize(30);
         server.setReuseAddress(true);
         server.bind(new InetSocketAddress(InetAddress.getLocalHost(),2500));
        
         int length;
         byte[] data=new byte[100];
         while(true)
         {
          try(Socket client=server.accept())
          {
          //here as well setting the client send buffer to 10 in an last attempt to make it send 10 bytes
           client.setSendBufferSize(10);
           try(InputStream input=client.getInputStream())
           {
            while((length=input.read(data))>0)
            {
             System.out.println(Arrays.toString(Arrays.copyOfRange(data,0,length)));
             System.out.println("============");
            }
           }
          }
         }
        }
       }

      Client run as an separate process[JVM]

      public static void main(String[] args)throws Exception
       {
        try(Socket client=new Socket())
        {
        //Set send buffer size before connecting
         client.setSendBufferSize(10);
         
         client.connect(new InetSocketAddress(InetAddress.getLocalHost(),2500));
        
         byte[] data=new byte[100];
         for(int i=0;i<data.length;i++){data[i]=(byte)i;}
         
         //set send buffer size one more time after connecting
         client.setSendBufferSize(10);
         
         //Verifying send buffer is actually 10. It is
         System.out.println(client.getSendBufferSize());
         
         try(OutputStream output=client.getOutputStream())
         {
          output.write(data);
         }
        }
       }

      Still sends 30 bytes of data even after setting it to 10 in 3 places[twice on the client side and one more time on the server side]
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround

      FREQUENCY : always


        1. Client.java
          0.8 kB
          Andrew Wang
        2. Screenshot 2022-05-12 162654.jpg
          504 kB
          Andrew Wang
        3. Server.java
          0.6 kB
          Andrew Wang
        4. Test Environment.mp4
          12.95 MB
          Andrew Wang

            djelinski Daniel Jelinski
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: