package org.limewire.rudp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.SocketChannel;
import org.limewire.nio.AbstractNBSocket;
import org.limewire.nio.channel.InterestReadableByteChannel;
import org.limewire.nio.channel.InterestWritableByteChannel;
/**
* A reliable UDP connection.
*/
class UDPConnection extends AbstractNBSocket implements RUDPSocket {
/** Channel backing the socket. */
private final UDPSocketChannel channel;
/** The default read timeout. */
private int soTimeout = 1 * 60 * 1000; // default to 1 minute.
/** The context surrounding this connection . */
private final RUDPContext context;
/**
* Creates an unconnected <code>UDPConnection</code>. You must call {@link #connect(SocketAddress) connect(...)} to connect.
*/
UDPConnection(RUDPContext context, UDPSocketChannel channel) {
this.context = context;
this.channel = channel;
setInitialReader();
setInitialWriter();
}
/** Returns the <code>UDPSocketChannel</code>, since it already implements
* <code>InterestReadChannel</code>. */
@Override
protected InterestReadableByteChannel getBaseReadChannel() {
return channel;
}
/** Returns the <code>UDPSocketChannel</code>, since it already implements
* <code>InterestWriteChannel</code>. */
@Override
protected InterestWritableByteChannel getBaseWriteChannel() {
return channel;
}
/** Doesn't do anything. */
@Override
protected void shutdownImpl() {
}
/** Sets the read timeout this socket should use. */
@Override
public void setSoTimeout(int timeout) {
soTimeout = timeout;
}
/** Returns the timeout this socket uses when reading. */
@Override
public int getSoTimeout() {
return soTimeout;
}
/** Returns the local address this socket uses. */
@Override
public InetAddress getLocalAddress() {
return context.getUDPService().getStableListeningAddress();
}
@Override
public SocketAddress getRemoteSocketAddress() {
return channel.getRemoteSocketAddress();
}
@Override
public InetAddress getInetAddress() {
return ((InetSocketAddress)getRemoteSocketAddress()).getAddress();
}
@Override
public int getPort() {
return ((InetSocketAddress)getRemoteSocketAddress()).getPort();
}
@Override
public int getLocalPort() {
return context.getUDPService().getStableListeningPort();
}
@Override
public SocketAddress getLocalSocketAddress() {
return new InetSocketAddress(getLocalAddress(), getLocalPort());
}
@Override
public SocketChannel getChannel() {
return channel;
}
@Override
public String toString() {
return "UDPConnection:" + channel;
}
@Override
public boolean isConnected() {
return channel.isConnected();
}
@Override
public boolean isBound() {
return true;
}
@Override
public boolean isClosed() {
return !channel.isOpen();
}
@Override
public boolean isInputShutdown() {
return !channel.isOpen();
}
@Override
public boolean isOutputShutdown() {
return !channel.isOpen();
}
@Override
public void bind(SocketAddress bindpoint) throws IOException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void setTcpNoDelay(boolean on) throws SocketException {
// does nothing
}
@Override
public boolean getTcpNoDelay() throws SocketException {
return true;
}
@Override
public void setSoLinger(boolean on, int linger) throws SocketException {
// does nothing
}
@Override
public int getSoLinger() throws SocketException {
return -1;
}
@Override
public void sendUrgentData(int data) throws IOException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void setOOBInline(boolean on) throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean getOOBInline() throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public synchronized void setSendBufferSize(int size) throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public synchronized int getSendBufferSize() throws SocketException {
return UDPConnectionProcessor.DATA_CHUNK_SIZE * UDPConnectionProcessor.DATA_WINDOW_SIZE;
}
@Override
public synchronized void setReceiveBufferSize(int size) throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public synchronized int getReceiveBufferSize() throws SocketException {
return UDPConnectionProcessor.MAX_DATA_SIZE * UDPConnectionProcessor.DATA_WINDOW_SIZE;
}
@Override
public void setKeepAlive(boolean on) throws SocketException {
// ignore
}
@Override
public boolean getKeepAlive() throws SocketException {
return true;
}
@Override
public void setTrafficClass(int tc) throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public int getTrafficClass() throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void setReuseAddress(boolean on) throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean getReuseAddress() throws SocketException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void shutdownInput() throws IOException {
throw new UnsupportedOperationException("not implemented");
}
@Override
public void shutdownOutput() throws IOException {
throw new UnsupportedOperationException("not implemented");
}
}