All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.grizzly.UDPConnectorHandler Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC1
Show newest version
/*
 * 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 */

package com.sun.grizzly;

import com.sun.grizzly.Controller.Protocol;
import com.sun.grizzly.util.InputReader;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AlreadyConnectedException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.DatagramChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

/**
 * Client side interface used to implement non blocking client operation.
 * Implementation of this class must make sure the following methods are
 * invoked in that order:
 * 


 * (1) connect()
 * (2) read() or write().
 * 

* * @author Jeanfrancois Arcand */ public class UDPConnectorHandler extends AbstractConnectorHandler { /** * IsConnected Latch related */ protected volatile CountDownLatch isConnectedLatch; /** * Are we creating a controller every run. */ private boolean isStandalone = false; public UDPConnectorHandler() { protocol(Protocol.UDP); } /** * Connect to hostname:port. When an aysnchronous event happens (e.g * OP_READ or OP_WRITE), the {@link Controller} will invoke * the CallBackHandler. * @param remoteAddress remote address to connect * @param localAddress local address to bin * @param callbackHandler the handler invoked by its associated {@link SelectorHandler} when * a non blocking operation is ready to be handled. When null, all * read and write operation will be delegated to the default * {@link ProtocolChain} and its list of {@link ProtocolFilter} * . When null, this {@link ConnectorHandler} will create an instance of {@link DefaultCallbackHandler}. * @param selectorHandler an instance of SelectorHandler. */ public void connect(SocketAddress remoteAddress, SocketAddress localAddress, CallbackHandler callbackHandler, UDPSelectorHandler selectorHandler) throws IOException { if (isConnected){ throw new AlreadyConnectedException(); } if (controller == null){ throw new IllegalStateException("Controller cannot be null"); } if (selectorHandler == null){ throw new IllegalStateException("Controller cannot be null"); } this.selectorHandler = selectorHandler; if (callbackHandler == null){ callbackHandler = new DefaultCallbackHandler(this); } else { this.callbackHandler = callbackHandler; } // Wait for the onConnect to be invoked. isConnectedLatch = new CountDownLatch(1); selectorHandler.connect(remoteAddress, localAddress, callbackHandler); try { isConnectedLatch.await(30, TimeUnit.SECONDS); } catch (InterruptedException ex) { throw new IOException(ex.getMessage()); } } /** * Connect to hostname:port. Internally an instance of Controller and * its default SelectorHandler will be created everytime this method is * called. This method should be used only and only if no external * Controller has been initialized. * @param remoteAddress remote address to connect * @param localAddress local address to bin */ public void connect(SocketAddress remoteAddress, SocketAddress localAddress) throws IOException { if (isConnected){ throw new AlreadyConnectedException(); } if (controller == null){ isStandalone = true; controller = new Controller(); controller.setSelectorHandler(new UDPSelectorHandler(true)); final CountDownLatch latch = new CountDownLatch(1); controller.addStateListener(new ControllerStateListenerAdapter() { @Override public void onReady() { latch.countDown(); } @Override public void onException(Throwable e) { latch.countDown(); } }); callbackHandler = new DefaultCallbackHandler(this, false); controller.executeUsingKernelExecutor(); try { latch.await(); } catch (InterruptedException ex) { } } connect(remoteAddress,localAddress,callbackHandler); } /** * {@inheritDoc} */ @Override public long read(ByteBuffer byteBuffer, boolean blocking) throws IOException { if (blocking){ if (inputStream == null) { inputStream = new InputReader(); } inputStream.setChannelType(InputReader.ChannelType.DatagramChannel); } return super.read( byteBuffer, blocking ); } /** * Receive bytes. * @param byteBuffer The byteBuffer to store bytes. * @param socketAddress * @return number bytes sent * @throws java.io.IOException */ public long send(ByteBuffer byteBuffer, SocketAddress socketAddress) throws IOException { if (!isConnected){ throw new NotYetConnectedException(); } if (callbackHandler == null){ throw new IllegalStateException ("Non blocking read needs a CallbackHandler"); } return ((DatagramChannel) underlyingChannel).send(byteBuffer,socketAddress); } /** * Receive bytes. * @param byteBuffer The byteBuffer to store bytes. * @return {@link SocketAddress} * @throws java.io.IOException */ public SocketAddress receive(ByteBuffer byteBuffer) throws IOException { if (!isConnected){ throw new NotYetConnectedException(); } if (callbackHandler == null){ throw new IllegalStateException ("Non blocking read needs a CallbackHandler"); } SocketAddress socketAddress = ((DatagramChannel) underlyingChannel).receive(byteBuffer); return socketAddress; } /** * Close the underlying connection. */ public void close() throws IOException{ if (underlyingChannel != null){ if (selectorHandler != null){ SelectionKey key = selectorHandler.keyFor(underlyingChannel); if (key == null) return; selectorHandler.getSelectionKeyHandler().cancel(key); } else { underlyingChannel.close(); } } if (controller != null && isStandalone){ controller.stop(); controller = null; } isStandalone = false; isConnected = false; } /** * Finish handling the OP_CONNECT interest ops. */ public void finishConnect(SelectionKey key) throws IOException { if (Controller.logger().isLoggable(Level.FINE)) { Controller.logger().log(Level.FINE, "Finish connect"); } final DatagramChannel datagramChannel = (DatagramChannel)key.channel(); underlyingChannel = datagramChannel; isConnected = datagramChannel.isConnected(); if (isConnectedLatch != null) { isConnectedLatch.countDown(); } } /** * A token decribing the protocol supported by an implementation of this * interface */ @Override public Controller.Protocol protocol(){ return Controller.Protocol.UDP; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy