001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.gravity.udp; 036 037import java.io.IOException; 038import java.net.InetSocketAddress; 039import java.net.SocketAddress; 040import java.nio.ByteBuffer; 041import java.nio.channels.DatagramChannel; 042 043import org.granite.gravity.AbstractChannel; 044 045/** 046 * @author Franck WOLFF 047 */ 048public class UdpNIOChannel extends AbstractUdpChannel { 049 050 private DatagramChannel channel = null; 051 052 public UdpNIOChannel(UdpChannelFactory channelFactory, AbstractChannel gravityChannel, DatagramChannel channel) { 053 this(channelFactory, gravityChannel, channel, null); 054 } 055 056 public UdpNIOChannel(UdpChannelFactory channelFactory, AbstractChannel gravityChannel, DatagramChannel channel, InetSocketAddress address) { 057 super(channelFactory, gravityChannel, address); 058 059 if ((address == null && !channel.isConnected()) || (address != null && channel.isConnected())) 060 throw new IllegalArgumentException("Inconsistent arguments"); 061 062 this.channel = channel; 063 } 064 065 public SocketAddress getClientAddress() { 066 return (channel.isConnected() ? channel.socket().getRemoteSocketAddress() : address); 067 } 068 069 @Override 070 public int getServerPort() { 071 return (channel.isConnected() ? channel.socket().getLocalPort() : address.getPort()); 072 } 073 074 public int write(byte[] data, int offset, int length) throws IOException { 075 int size = length - offset; 076 077 if (size > MAX_PACKET_SIZE) 078 throw new UdpPacketTooLargeException("UDP packet size cannot exceed 64K: " + size); 079 080 ByteBuffer buf = ByteBuffer.wrap(data, offset, length); 081 return (channel.isConnected() ? channel.write(buf) : channel.send(buf, address)); 082 } 083 084 public void close() { 085 super.close(); 086 087 try { 088 if (channel.isConnected()) { 089 try { 090 channel.close(); 091 } 092 catch (IOException e) { 093 throw new RuntimeException(e); 094 } 095 } 096 } 097 finally { 098 channel = null; 099 } 100 } 101}