diff options
Diffstat (limited to 'engine/src/networking/com/jme3/network/kernel/udp/UdpConnector.java')
-rw-r--r-- | engine/src/networking/com/jme3/network/kernel/udp/UdpConnector.java | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/engine/src/networking/com/jme3/network/kernel/udp/UdpConnector.java b/engine/src/networking/com/jme3/network/kernel/udp/UdpConnector.java new file mode 100644 index 0000000..0193e1c --- /dev/null +++ b/engine/src/networking/com/jme3/network/kernel/udp/UdpConnector.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2011 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.network.kernel.udp; + +import com.jme3.network.kernel.Connector; +import com.jme3.network.kernel.ConnectorException; +import java.io.IOException; +import java.net.*; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicBoolean; + + +/** + * A straight forward datagram socket-based UDP connector + * implementation. + * + * @version $Revision: 8843 $ + * @author Paul Speed + */ +public class UdpConnector implements Connector +{ + private DatagramSocket sock = new DatagramSocket(); + private SocketAddress remoteAddress; + private byte[] buffer = new byte[65535]; + private AtomicBoolean connected = new AtomicBoolean(false); + + /** + * In order to provide proper available() checking, we + * potentially queue one datagram. + */ + private DatagramPacket pending; + + /** + * Creates a new UDP connection that send datagrams to the + * specified address and port. + */ + public UdpConnector( InetAddress remote, int remotePort ) throws IOException + { + InetSocketAddress localSocketAddress = new InetSocketAddress(0); + this.sock = new DatagramSocket( localSocketAddress ); + remoteAddress = new InetSocketAddress( remote, remotePort ); + + // Setup to receive only from the remote address + sock.connect( remoteAddress ); + + connected.set(true); + } + + protected void checkClosed() + { + if( sock == null ) + throw new ConnectorException( "Connection is closed:" + remoteAddress ); + } + + public boolean isConnected() + { + if( sock == null ) + return false; + return sock.isConnected(); + } + + public void close() + { + checkClosed(); + DatagramSocket temp = sock; + sock = null; + connected.set(false); + temp.close(); + } + + /** + * This always returns false since the simple DatagramSocket usage + * cannot be run in a non-blocking way. + */ + public boolean available() + { + // It would take a separate thread or an NIO Selector based implementation to get this + // to work. If a polling strategy is never employed by callers then it doesn't + // seem worth it to implement all of that just for this method. + checkClosed(); + return false; + } + + public ByteBuffer read() + { + checkClosed(); + + try { + DatagramPacket packet = new DatagramPacket( buffer, buffer.length ); + sock.receive(packet); + + // Wrap it in a ByteBuffer for the caller + return ByteBuffer.wrap( buffer, 0, packet.getLength() ); + } catch( IOException e ) { + if( !connected.get() ) { + // Nothing to see here... just move along + return null; + } + throw new ConnectorException( "Error reading from connection to:" + remoteAddress, e ); + } + } + + public void write( ByteBuffer data ) + { + checkClosed(); + + try { + DatagramPacket p = new DatagramPacket( data.array(), data.position(), data.remaining(), + remoteAddress ); + sock.send(p); + } catch( IOException e ) { + throw new ConnectorException( "Error writing to connection:" + remoteAddress, e ); + } + } +} + |