public DatagramChannel connect(SocketAddress sa) throws IOException {
    int localPort = 0;

    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          ensureOpenAndUnconnected();
          InetSocketAddress isa = Net.checkAddress(sa);
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          int n = Net.connect(family, fd, isa.getAddress(), isa.getPort());
          if (n <= 0) throw new Error(); // Can't happen

          // Connection succeeded; disallow further invocation
          state = ST_CONNECTED;
          remoteAddress = sa;
          sender = isa;
          cachedSenderInetAddress = isa.getAddress();
          cachedSenderPort = isa.getPort();

          // set or refresh local address
          localAddress = Net.localAddress(fd);
        }
      }
    }
    return this;
  }
  private JarFile getCachedJarFile(URL url) {
    JarFile result = (JarFile) fileCache.get(url);

    /* if the JAR file is cached, the permission will always be there */
    if (result != null) {
      Permission perm = getPermission(result);
      if (perm != null) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
          try {
            sm.checkPermission(perm);
          } catch (SecurityException se) {
            // fallback to checkRead/checkConnect for pre 1.2
            // security managers
            if ((perm instanceof java.io.FilePermission)
                && perm.getActions().indexOf("read") != -1) {
              sm.checkRead(perm.getName());
            } else if ((perm instanceof java.net.SocketPermission)
                && perm.getActions().indexOf("connect") != -1) {
              sm.checkConnect(url.getHost(), url.getPort());
            } else {
              throw se;
            }
          }
        }
      }
    }
    return result;
  }
  public int send(ByteBuffer src, SocketAddress target) throws IOException {
    if (src == null) throw new NullPointerException();

    synchronized (writeLock) {
      ensureOpen();
      InetSocketAddress isa = Net.checkAddress(target);
      InetAddress ia = isa.getAddress();
      if (ia == null) throw new IOException("Target address not resolved");
      synchronized (stateLock) {
        if (!isConnected()) {
          if (target == null) throw new NullPointerException();
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) {
            if (ia.isMulticastAddress()) {
              sm.checkMulticast(ia);
            } else {
              sm.checkConnect(ia.getHostAddress(), isa.getPort());
            }
          }
        } else { // Connected case; Check address then write
          if (!target.equals(remoteAddress)) {
            throw new IllegalArgumentException("Connected address not equal to target address");
          }
          return write(src);
        }
      }

      int n = 0;
      try {
        begin();
        if (!isOpen()) return 0;
        writerThread = NativeThread.current();
        do {
          n = send(fd, src, isa);
        } while ((n == IOStatus.INTERRUPTED) && isOpen());

        synchronized (stateLock) {
          if (isOpen() && (localAddress == null)) {
            localAddress = Net.localAddress(fd);
          }
        }
        return IOStatus.normalize(n);
      } finally {
        writerThread = 0;
        end((n > 0) || (n == IOStatus.UNAVAILABLE));
        assert IOStatus.check(n);
      }
    }
  }
  @Override
  public DatagramChannel connect(SocketAddress sa) throws IOException {
    int localPort = 0;

    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          ensureOpenAndUnconnected();
          InetSocketAddress isa = Net.checkAddress(sa);
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          int n = Net.connect(family, fd, isa.getAddress(), isa.getPort());
          if (n <= 0) throw new Error(); // Can't happen

          // Connection succeeded; disallow further invocation
          state = ST_CONNECTED;
          remoteAddress = isa;
          sender = isa;
          cachedSenderInetAddress = isa.getAddress();
          cachedSenderPort = isa.getPort();

          // set or refresh local address
          localAddress = Net.localAddress(fd);

          // flush any packets already received.
          boolean blocking = false;
          synchronized (blockingLock()) {
            try {
              blocking = isBlocking();
              // remainder of each packet thrown away
              ByteBuffer tmpBuf = ByteBuffer.allocate(1);
              if (blocking) {
                configureBlocking(false);
              }
              do {
                tmpBuf.clear();
              } while (receive(tmpBuf) != null);
            } finally {
              if (blocking) {
                configureBlocking(true);
              }
            }
          }
        }
      }
    }
    return this;
  }
  public DatagramChannel disconnect() throws IOException {
    synchronized (readLock) {
      synchronized (writeLock) {
        synchronized (stateLock) {
          if (!isConnected() || !isOpen()) return this;
          InetSocketAddress isa = (InetSocketAddress) remoteAddress;
          SecurityManager sm = System.getSecurityManager();
          if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort());
          disconnect0(fd);
          remoteAddress = null;
          state = ST_UNCONNECTED;

          // refresh local address
          localAddress = Net.localAddress(fd);
        }
      }
    }
    return this;
  }