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;
  }
  @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;
  }