jdk/src/java.base/share/classes/java/net/DatagramSocket.java
changeset 27078 39275d6a8cac
parent 25859 3317bb8137f4
child 27724 9a42fe09eb61
equal deleted inserted replaced
27077:c943ca4a3380 27078:39275d6a8cac
    83     /**
    83     /**
    84      * Are we using an older DatagramSocketImpl?
    84      * Are we using an older DatagramSocketImpl?
    85      */
    85      */
    86     boolean oldImpl = false;
    86     boolean oldImpl = false;
    87 
    87 
       
    88     /**
       
    89      * Set when a socket is ST_CONNECTED until we are certain
       
    90      * that any packets which might have been received prior
       
    91      * to calling connect() but not read by the application
       
    92      * have been read. During this time we check the source
       
    93      * address of all packets received to be sure they are from
       
    94      * the connected destination. Other packets are read but
       
    95      * silently dropped.
       
    96      */
       
    97     private boolean explicitFilter = false;
       
    98     private int bytesLeftToFilter;
    88     /*
    99     /*
    89      * Connection state:
   100      * Connection state:
    90      * ST_NOT_CONNECTED = socket not connected
   101      * ST_NOT_CONNECTED = socket not connected
    91      * ST_CONNECTED = socket connected
   102      * ST_CONNECTED = socket connected
    92      * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
   103      * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
   142             try {
   153             try {
   143                 getImpl().connect(address, port);
   154                 getImpl().connect(address, port);
   144 
   155 
   145                 // socket is now connected by the impl
   156                 // socket is now connected by the impl
   146                 connectState = ST_CONNECTED;
   157                 connectState = ST_CONNECTED;
       
   158                 // Do we need to filter some packets?
       
   159                 int avail = getImpl().dataAvailable();
       
   160                 if (avail == -1) {
       
   161                     throw new SocketException();
       
   162                 }
       
   163                 explicitFilter = avail > 0;
       
   164                 if (explicitFilter) {
       
   165                     bytesLeftToFilter = getReceiveBufferSize();
       
   166                 }
   147             } catch (SocketException se) {
   167             } catch (SocketException se) {
   148 
   168 
   149                 // connection will be emulated by DatagramSocket
   169                 // connection will be emulated by DatagramSocket
   150                 connectState = ST_CONNECTED_NO_IMPL;
   170                 connectState = ST_CONNECTED_NO_IMPL;
   151             }
   171             }
   490                 impl.disconnect ();
   510                 impl.disconnect ();
   491             }
   511             }
   492             connectedAddress = null;
   512             connectedAddress = null;
   493             connectedPort = -1;
   513             connectedPort = -1;
   494             connectState = ST_NOT_CONNECTED;
   514             connectState = ST_NOT_CONNECTED;
       
   515             explicitFilter = false;
   495         }
   516         }
   496     }
   517     }
   497 
   518 
   498     /**
   519     /**
   499      * Returns the binding state of the socket.
   520      * Returns the binding state of the socket.
   748                             continue;
   769                             continue;
   749                         }
   770                         }
   750                     } // end of while
   771                     } // end of while
   751                 }
   772                 }
   752             }
   773             }
   753             if (connectState == ST_CONNECTED_NO_IMPL) {
   774             if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
   754                 // We have to do the filtering the old fashioned way since
   775                 // We have to do the filtering the old fashioned way since
   755                 // the native impl doesn't support connect or the connect
   776                 // the native impl doesn't support connect or the connect
   756                 // via the impl failed.
   777                 // via the impl failed, or .. "explicitFilter" may be set when
       
   778                 // a socket is connected via the impl, for a period of time
       
   779                 // when packets from other sources might be queued on socket.
   757                 boolean stop = false;
   780                 boolean stop = false;
   758                 while (!stop) {
   781                 while (!stop) {
   759                     InetAddress peekAddress = null;
   782                     InetAddress peekAddress = null;
   760                     int peekPort = -1;
   783                     int peekPort = -1;
   761                     // peek at the packet to see who it is from.
   784                     // peek at the packet to see who it is from.
   770                         peekPort = getImpl().peek(peekAddress);
   793                         peekPort = getImpl().peek(peekAddress);
   771                     }
   794                     }
   772                     if ((!connectedAddress.equals(peekAddress)) ||
   795                     if ((!connectedAddress.equals(peekAddress)) ||
   773                         (connectedPort != peekPort)) {
   796                         (connectedPort != peekPort)) {
   774                         // throw the packet away and silently continue
   797                         // throw the packet away and silently continue
   775                         DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
   798                         DatagramPacket tmp = new DatagramPacket(
       
   799                                                 new byte[1024], 1024);
   776                         getImpl().receive(tmp);
   800                         getImpl().receive(tmp);
       
   801                         if (explicitFilter) {
       
   802                             bytesLeftToFilter -= tmp.getLength();
       
   803                         }
   777                     } else {
   804                     } else {
   778                         stop = true;
   805                         stop = true;
   779                     }
   806                     }
   780                 }
   807                 }
   781             }
   808             }
   782             // If the security check succeeds, or the datagram is
   809             // If the security check succeeds, or the datagram is
   783             // connected then receive the packet
   810             // connected then receive the packet
   784             getImpl().receive(p);
   811             getImpl().receive(p);
       
   812             if (explicitFilter) {
       
   813                 bytesLeftToFilter -= p.getLength();
       
   814                 if (bytesLeftToFilter <= 0) {
       
   815                     explicitFilter = false;
       
   816                 } else {
       
   817                     // break out of filter, if there is no more data queued
       
   818                     explicitFilter = getImpl().dataAvailable() > 0;
       
   819                 }
       
   820             }
   785         }
   821         }
   786     }
   822     }
   787 
   823 
   788     /**
   824     /**
   789      * Gets the local address to which the socket is bound.
   825      * Gets the local address to which the socket is bound.