diff options
Diffstat (limited to 'plugins/org.eclipse.net4j.tcp/src')
20 files changed, 1776 insertions, 0 deletions
diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/AbstractTCPConnector.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/AbstractTCPConnector.java new file mode 100644 index 0000000000..a8adbc4215 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/AbstractTCPConnector.java @@ -0,0 +1,345 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPSelector; +import org.eclipse.net4j.tcp.TCPSelectorListener; +import org.eclipse.net4j.transport.Buffer; +import org.eclipse.net4j.transport.Channel; +import org.eclipse.net4j.transport.ConnectorException; +import org.eclipse.net4j.transport.ConnectorState; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.internal.net4j.bundle.Net4j; +import org.eclipse.internal.net4j.transport.AbstractConnector; +import org.eclipse.internal.net4j.transport.ChannelImpl; + +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.List; +import java.util.Queue; + +/** + * @author Eike Stepper + */ +public abstract class AbstractTCPConnector extends AbstractConnector implements TCPSelectorListener.Active +{ + private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_CONNECTOR, AbstractTCPConnector.class); + + private SocketChannel socketChannel; + + private TCPSelector selector; + + private SelectionKey selectionKey; + + private Buffer inputBuffer; + + private ControlChannelImpl controlChannel; + + public AbstractTCPConnector() + { + } + + public TCPSelector getSelector() + { + return selector; + } + + public void setSelector(TCPSelector selector) + { + this.selector = selector; + } + + public SocketChannel getSocketChannel() + { + return socketChannel; + } + + /** + * SocketChannel must already be non-blocking! + */ + public void setSocketChannel(SocketChannel socketChannel) + { + this.socketChannel = socketChannel; + } + + /** + * Called by {@link ChannelImpl} each time a new buffer is available for + * multiplexing. This or another buffer can be dequeued from the outputQueue + * of the {@link ChannelImpl}. + */ + public void multiplexBuffer(Channel channel) + { + checkSelectionKey(); + selector.setWriteInterest(selectionKey, true); + } + + public void registered(SelectionKey selectionKey) + { + this.selectionKey = selectionKey; + if (isServer()) + { + selector.setConnectInterest(selectionKey, false); + } + } + + public void handleConnect(TCPSelector selector, SocketChannel channel) + { + try + { + if (!channel.finishConnect()) + { + return; + } + } + catch (Exception ex) + { + return; + } + + try + { + checkSelectionKey(); + selector.setConnectInterest(selectionKey, false); + setState(ConnectorState.NEGOTIATING); + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + deactivate(); + } + } + + public void handleRead(TCPSelector selector, SocketChannel socketChannel) + { + try + { + if (inputBuffer == null) + { + inputBuffer = getBufferProvider().provideBuffer(); + } + + ByteBuffer byteBuffer = inputBuffer.startGetting(socketChannel); + if (byteBuffer != null) + { + short channelIndex = inputBuffer.getChannelIndex(); + ChannelImpl channel = channelIndex == ControlChannelImpl.CONTROL_CHANNEL_ID ? controlChannel + : getChannel(channelIndex); + if (channel != null) + { + channel.handleBufferFromMultiplexer(inputBuffer); + } + else + { + if (TRACER.isEnabled()) + { + TRACER.trace("Discarding buffer from unknown channel"); //$NON-NLS-1$ + } + + inputBuffer.release(); + } + + inputBuffer = null; + } + } + catch (ClosedChannelException ex) + { + deactivate(); + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + deactivate(); + } + } + + public void handleWrite(TCPSelector selector, SocketChannel socketChannel) + { + try + { + boolean moreToWrite = false; + for (Queue<Buffer> bufferQueue : getChannelBufferQueues()) + { + Buffer buffer = bufferQueue.peek(); + if (buffer != null) + { + if (buffer.write(socketChannel)) + { + bufferQueue.poll(); + buffer.release(); + + if (!moreToWrite) + { + moreToWrite = !bufferQueue.isEmpty(); + } + } + else + { + moreToWrite = true; + break; + } + } + } + + if (!moreToWrite) + { + checkSelectionKey(); + selector.setWriteInterest(selectionKey, false); + } + } + catch (NullPointerException ignore) + { + ; + } + catch (ClosedChannelException ex) + { + deactivate(); + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + deactivate(); + } + } + + @Override + protected List<Queue<Buffer>> getChannelBufferQueues() + { + List<Queue<Buffer>> queues = super.getChannelBufferQueues(); + Queue<Buffer> controlQueue = controlChannel.getSendQueue(); + if (!controlQueue.isEmpty()) + { + queues.add(controlQueue); + } + + return queues; + } + + @Override + protected void registerChannelWithPeer(short channelIndex, String protocolID) throws ConnectorException + { + try + { + if (!controlChannel.registerChannel(channelIndex, protocolID)) + { + throw new ConnectorException("Failed to register channel with peer"); //$NON-NLS-1$ + } + } + catch (ConnectorException ex) + { + throw ex; + } + catch (Exception ex) + { + throw new ConnectorException(ex); + } + } + + @Override + protected void removeChannel(ChannelImpl channel) + { + if (isConnected()) + { + controlChannel.deregisterChannel(channel.getChannelIndex()); + } + + super.removeChannel(channel); + } + + @Override + protected void onAboutToActivate() throws Exception + { + super.onAboutToActivate(); + if (socketChannel == null) + { + throw new IllegalStateException("socketChannel == null"); + } + + if (selector == null) + { + throw new IllegalStateException("selector == null"); + } + } + + @Override + protected void onActivate() throws Exception + { + super.onActivate(); + controlChannel = new ControlChannelImpl(this); + controlChannel.activate(); + selector.registerAsync(socketChannel, this); + } + + @Override + protected void onDeactivate() throws Exception + { + Exception exception = null; + + try + { + controlChannel.deactivate(); + } + catch (Exception ex) + { + if (exception == null) + { + exception = ex; + } + } + finally + { + controlChannel = null; + } + + try + { + socketChannel.close(); + } + catch (Exception ex) + { + if (exception == null) + { + exception = ex; + } + } + finally + { + socketChannel = null; + } + + try + { + super.onDeactivate(); + } + catch (Exception ex) + { + if (exception == null) + { + exception = ex; + } + } + + if (exception != null) + { + throw exception; + } + } + + private void checkSelectionKey() + { + if (selectionKey == null) + { + throw new IllegalStateException("selectionKey == null"); + } + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ClientTCPConnectorImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ClientTCPConnectorImpl.java new file mode 100644 index 0000000000..0d8d7c1822 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ClientTCPConnectorImpl.java @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.transport.ConnectorLocation; + +import org.eclipse.internal.net4j.bundle.Net4j; +import org.eclipse.internal.net4j.transport.DescriptionUtil; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.channels.SocketChannel; +import java.text.MessageFormat; + +/** + * @author Eike Stepper + */ +public class ClientTCPConnectorImpl extends AbstractTCPConnector +{ + public ClientTCPConnectorImpl() + { + try + { + SocketChannel socketChannel = SocketChannel.open(); + socketChannel.configureBlocking(false); + setSocketChannel(socketChannel); + } + catch (IOException ex) + { + Net4j.LOG.error(ex); + } + } + + public ConnectorLocation getLocation() + { + return ConnectorLocation.CLIENT; + } + + @Override + public String toString() + { + return MessageFormat.format("ClientTCPConnector[{0}]", getDescription()); //$NON-NLS-1$ + } + + @Override + protected void onAboutToActivate() throws Exception + { + super.onAboutToActivate(); + if (getDescription() == null) + { + throw new IllegalStateException("getDescription() == null"); //$NON-NLS-1$ + } + } + + @Override + protected void onActivate() throws Exception + { + super.onActivate(); + + String[] elements = DescriptionUtil.getElements(getDescription()); + String host = elements[1]; + int port = Integer.parseInt(elements[2]); + + InetAddress addr = InetAddress.getByName(host); + InetSocketAddress sAddr = new InetSocketAddress(addr, port); + getSocketChannel().connect(sAddr); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannelImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannelImpl.java new file mode 100644 index 0000000000..afbc06f66b --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ControlChannelImpl.java @@ -0,0 +1,188 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.transport.Buffer; +import org.eclipse.net4j.util.concurrent.ISynchronizer; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.internal.net4j.bundle.Net4j; +import org.eclipse.internal.net4j.transport.BufferUtil; +import org.eclipse.internal.net4j.transport.ChannelImpl; +import org.eclipse.internal.net4j.util.concurrent.SynchronizingCorrelator; + +import java.nio.ByteBuffer; + +/** + * @author Eike Stepper + */ +public final class ControlChannelImpl extends ChannelImpl +{ + public static final short CONTROL_CHANNEL_ID = -1; + + public static final long REGISTRATION_TIMEOUT = 500000; + + public static final byte OPCODE_REGISTRATION = 1; + + public static final byte OPCODE_REGISTRATION_ACK = 2; + + public static final byte OPCODE_DEREGISTRATION = 3; + + public static final byte SUCCESS = 1; + + public static final byte FAILURE = 0; + + private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_CHANNEL, ControlChannelImpl.class); + + private SynchronizingCorrelator<Short, Boolean> registrations = new SynchronizingCorrelator(); + + public ControlChannelImpl(AbstractTCPConnector connector) + { + super(connector.getReceiveExecutor()); + setChannelIndex(CONTROL_CHANNEL_ID); + setConnector(connector); + } + + @Override + public boolean isInternal() + { + return true; + } + + public boolean registerChannel(short channelIndex, String protocolID) + { + assertValidChannelIndex(channelIndex); + ISynchronizer<Boolean> registration = registrations.correlate(channelIndex); + + Buffer buffer = provideBuffer(); + ByteBuffer byteBuffer = buffer.startPutting(CONTROL_CHANNEL_ID); + byteBuffer.put(OPCODE_REGISTRATION); + byteBuffer.putShort(channelIndex); + BufferUtil.putUTF8(byteBuffer, protocolID); + handleBuffer(buffer); + + return registration.get(REGISTRATION_TIMEOUT); + } + + public void deregisterChannel(short channelIndex) + { + assertValidChannelIndex(channelIndex); + + Buffer buffer = provideBuffer(); + ByteBuffer byteBuffer = buffer.startPutting(CONTROL_CHANNEL_ID); + byteBuffer.put(OPCODE_DEREGISTRATION); + byteBuffer.putShort(channelIndex); + handleBuffer(buffer); + } + + public void handleBufferFromMultiplexer(Buffer buffer) + { + try + { + ByteBuffer byteBuffer = buffer.getByteBuffer(); + byte opcode = byteBuffer.get(); + switch (opcode) + { + case OPCODE_REGISTRATION: + { + short channelIndex = byteBuffer.getShort(); + assertValidChannelIndex(channelIndex); + boolean success = true; + + try + { + byte[] handlerFactoryUTF8 = BufferUtil.getByteArray(byteBuffer); + String protocolID = BufferUtil.fromUTF8(handlerFactoryUTF8); + ChannelImpl channel = ((AbstractTCPConnector)getConnector()).createChannel(channelIndex, protocolID, null); + if (channel != null) + { + channel.activate(); + } + else + { + success = false; + } + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + success = false; + } + + sendStatus(OPCODE_REGISTRATION_ACK, channelIndex, success); + break; + } + + case OPCODE_REGISTRATION_ACK: + { + short channelIndex = byteBuffer.getShort(); + boolean success = byteBuffer.get() == SUCCESS; + registrations.put(channelIndex, success); + break; + } + + case OPCODE_DEREGISTRATION: + { + short channelIndex = byteBuffer.getShort(); + assertValidChannelIndex(channelIndex); + + try + { + ChannelImpl channel = ((AbstractTCPConnector)getConnector()).getChannel(channelIndex); + if (channel != null) + { + channel.deactivate(); + } + else + { + if (TRACER.isEnabled()) + { + TRACER.trace("Invalid channel id: " + channelIndex); //$NON-NLS-1$ + } + } + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + } + + break; + } + + default: + Net4j.LOG.error("Invalid opcode: " + opcode); //$NON-NLS-1$ + ((AbstractTCPConnector)getConnector()).deactivate(); + } + } + finally + { + buffer.release(); + } + } + + private void sendStatus(byte opcode, short channelIndex, boolean status) + { + Buffer buffer = provideBuffer(); + ByteBuffer byteBuffer = buffer.startPutting(CONTROL_CHANNEL_ID); + byteBuffer.put(opcode); + byteBuffer.putShort(channelIndex); + byteBuffer.put(status ? SUCCESS : FAILURE); + handleBuffer(buffer); + } + + private void assertValidChannelIndex(short channelIndex) + { + if (channelIndex <= CONTROL_CHANNEL_ID) + { + throw new IllegalArgumentException("channelIndex <= CONTROL_CHANNEL_ID"); //$NON-NLS-1$ + } + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/SelectorUtil.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/SelectorUtil.java new file mode 100644 index 0000000000..fdb1685c04 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/SelectorUtil.java @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.internal.net4j.bundle.Net4j; + +import java.nio.channels.SelectionKey; + +/** + * @author Eike Stepper + */ +public final class SelectorUtil +{ + private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_SELECTOR, SelectorUtil.class); + + private SelectorUtil() + { + } + + public static String formatInterestOps(int newOps) + { + StringBuilder builder = new StringBuilder(); + if ((newOps & SelectionKey.OP_ACCEPT) != 0) + { + addInterestOp(builder, "ACCEPT"); //$NON-NLS-1$ + } + + if ((newOps & SelectionKey.OP_CONNECT) != 0) + { + addInterestOp(builder, "CONNECT"); //$NON-NLS-1$ + } + + if ((newOps & SelectionKey.OP_READ) != 0) + { + addInterestOp(builder, "READ"); //$NON-NLS-1$ + } + + if ((newOps & SelectionKey.OP_WRITE) != 0) + { + addInterestOp(builder, "WRITE"); //$NON-NLS-1$ + } + + return builder.toString(); + } + + public static void setInterest(SelectionKey selectionKey, int operation, boolean interested) + { + if (selectionKey == null || !selectionKey.isValid()) + { + return; + } + + int newOps; + int oldOps = selectionKey.interestOps(); + if (interested) + { + newOps = oldOps | operation; + } + else + { + newOps = oldOps & ~operation; + } + + if (oldOps != newOps) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Setting interest " //$NON-NLS-1$ + + formatInterestOps(newOps) + " (was " + formatInterestOps(oldOps).toLowerCase() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + selectionKey.interestOps(newOps); + } + } + + public static void setAcceptInterest(SelectionKey selectionKey, boolean interested) + { + setInterest(selectionKey, SelectionKey.OP_ACCEPT, interested); + } + + public static void setConnectInterest(SelectionKey selectionKey, boolean interested) + { + setInterest(selectionKey, SelectionKey.OP_CONNECT, interested); + } + + public static void setReadInterest(SelectionKey selectionKey, boolean interested) + { + setInterest(selectionKey, SelectionKey.OP_READ, interested); + } + + public static void setWriteInterest(SelectionKey selectionKey, boolean interested) + { + setInterest(selectionKey, SelectionKey.OP_WRITE, interested); + } + + private static void addInterestOp(StringBuilder builder, String op) + { + if (builder.length() != 0) + { + builder.append("|"); //$NON-NLS-1$ + } + + builder.append(op); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ServerTCPConnectorImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ServerTCPConnectorImpl.java new file mode 100644 index 0000000000..8bf1fca41e --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/ServerTCPConnectorImpl.java @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.transport.ConnectorLocation; + +import java.text.MessageFormat; + +/** + * @author Eike Stepper + */ +public class ServerTCPConnectorImpl extends AbstractTCPConnector +{ + public ServerTCPConnectorImpl() + { + } + + public ConnectorLocation getLocation() + { + return ConnectorLocation.SERVER; + } + + public String getHost() + { + return getSocketChannel().socket().getInetAddress().getHostAddress(); + } + + public int getPort() + { + return getSocketChannel().socket().getPort(); + } + + @Override + public String toString() + { + return MessageFormat.format("ServerTCPConnector[{0}]", getDescription()); //$NON-NLS-1$ + } + + @Override + protected void onDeactivate() throws Exception + { + super.onDeactivate(); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorFactoryImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorFactoryImpl.java new file mode 100644 index 0000000000..cbf482f1ca --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorFactoryImpl.java @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPAcceptorFactory; +import org.eclipse.net4j.transport.Acceptor; + +/** + * @author Eike Stepper + */ +public class TCPAcceptorFactoryImpl implements TCPAcceptorFactory +{ + public String getType() + { + return TYPE; + } + + public Acceptor createAcceptor() + { + return new TCPAcceptorImpl(); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorImpl.java new file mode 100644 index 0000000000..7e94c2630f --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPAcceptorImpl.java @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPSelector; +import org.eclipse.net4j.tcp.TCPSelectorListener; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.internal.net4j.bundle.Net4j; +import org.eclipse.internal.net4j.transport.AbstractAcceptor; +import org.eclipse.internal.net4j.transport.DescriptionUtil; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.text.MessageFormat; + +/** + * @author Eike Stepper + */ +public class TCPAcceptorImpl extends AbstractAcceptor implements TCPSelectorListener.Passive +{ + private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_ACCEPTOR, TCPAcceptorImpl.class); + + private TCPSelector selector; + + private ServerSocketChannel serverSocketChannel; + + public TCPAcceptorImpl() + { + } + + public TCPSelector getSelector() + { + return selector; + } + + public void setSelector(TCPSelector selector) + { + this.selector = selector; + } + + public void handleAccept(TCPSelector selector, ServerSocketChannel serverSocketChannel) + { + try + { + SocketChannel socketChannel = serverSocketChannel.accept(); + if (socketChannel != null) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Accepted socketChannel " + socketChannel); //$NON-NLS-1$ + } + + socketChannel.configureBlocking(false); + ServerTCPConnectorImpl connector = createConnector(socketChannel); + addConnector(connector); + } + } + catch (ClosedChannelException ex) + { + deactivate(); + } + catch (Exception ex) + { + if (isActive()) + { + Net4j.LOG.error(ex); + } + + deactivate(); + } + } + + @Override + public String toString() + { + return MessageFormat.format("TCPAcceptor[{0}]", getDescription()); //$NON-NLS-1$ + } + + protected ServerTCPConnectorImpl createConnector(SocketChannel socketChannel) + { + ServerTCPConnectorImpl connector = new ServerTCPConnectorImpl(); + connector.setSocketChannel(socketChannel); + connector.setReceiveExecutor(getReceiveExecutor()); + connector.setProtocolFactoryRegistry(getProtocolFactoryRegistry()); + connector.setBufferProvider(getBufferProvider()); + connector.setSelector(selector); + return connector; + } + + @Override + protected void onAboutToActivate() throws Exception + { + super.onAboutToActivate(); + if (getDescription() == null) + { + throw new IllegalStateException("getDescription() == null"); //$NON-NLS-1$ + } + + if (selector == null) + { + throw new IllegalStateException("selector == null"); + } + } + + @Override + protected void onActivate() throws Exception + { + super.onActivate(); + + String[] elements = DescriptionUtil.getElements(getDescription()); + String address = elements[1]; + int port = Integer.parseInt(elements[2]); + + InetAddress addr = InetAddress.getByName(address); + InetSocketAddress sAddr = new InetSocketAddress(addr, port); + + serverSocketChannel = ServerSocketChannel.open(); + serverSocketChannel.configureBlocking(false); + serverSocketChannel.socket().bind(sAddr); + + selector.registerAsync(serverSocketChannel, this); + } + + @Override + protected void onDeactivate() throws Exception + { + serverSocketChannel.close(); + super.onDeactivate(); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnectorFactoryImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnectorFactoryImpl.java new file mode 100644 index 0000000000..31bc98bf61 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPConnectorFactoryImpl.java @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPConnectorFactory; +import org.eclipse.net4j.transport.Connector; + +/** + * @author Eike Stepper + */ +public class TCPConnectorFactoryImpl implements TCPConnectorFactory +{ + public String getType() + { + return TYPE; + } + + public Connector createConnector() + { + return new ClientTCPConnectorImpl(); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterFactoryImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterFactoryImpl.java new file mode 100644 index 0000000000..a60876f4be --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterFactoryImpl.java @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPContainerAdapter; +import org.eclipse.net4j.transport.container.Container; +import org.eclipse.net4j.transport.container.ContainerAdapter; +import org.eclipse.net4j.transport.container.ContainerAdapterFactory; + +public final class TCPContainerAdapterFactoryImpl implements ContainerAdapterFactory +{ + public TCPContainerAdapterFactoryImpl() + { + } + + public String getType() + { + return TCPContainerAdapter.TYPE; + } + + public ContainerAdapter createAdapter(Container container) + { + return new TCPContainerAdapterImpl(container); + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterImpl.java new file mode 100644 index 0000000000..8fc8fd8dcf --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPContainerAdapterImpl.java @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPContainerAdapter; +import org.eclipse.net4j.tcp.TCPSelector; +import org.eclipse.net4j.transport.Acceptor; +import org.eclipse.net4j.transport.AcceptorFactory; +import org.eclipse.net4j.transport.Connector; +import org.eclipse.net4j.transport.ConnectorFactory; +import org.eclipse.net4j.transport.container.Container; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; + +import org.eclipse.internal.net4j.transport.container.TransportContainerAdapter; + +/** + * @author Eike Stepper + */ +public class TCPContainerAdapterImpl extends TransportContainerAdapter implements TCPContainerAdapter +{ + private TCPSelector selector; + + public TCPContainerAdapterImpl(Container container) + { + super(container, TYPE); + selector = new TCPSelectorImpl(); + } + + public TCPSelector getSelector() + { + return selector; + } + + @Override + protected void onActivate() throws Exception + { + super.onActivate(); + LifecycleUtil.activate(selector); + } + + @Override + protected void onDeactivate() throws Exception + { + LifecycleUtil.deactivate(selector); + super.onDeactivate(); + } + + protected AcceptorFactory createAcceptorFactory() + { + return new TCPAcceptorFactoryImpl(); + } + + protected ConnectorFactory createConnectorFactory() + { + return new TCPConnectorFactoryImpl(); + } + + public void initAcceptor(Acceptor acceptor) + { + TCPAcceptorImpl tcpAcceptor = (TCPAcceptorImpl)acceptor; + tcpAcceptor.setSelector(getSelector()); + } + + public void initConnector(Connector connector) + { + AbstractTCPConnector tcpConnector = (AbstractTCPConnector)connector; + tcpConnector.setSelector(getSelector()); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPSelectorImpl.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPSelectorImpl.java new file mode 100644 index 0000000000..ffcdb370a5 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/TCPSelectorImpl.java @@ -0,0 +1,372 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp; + +import org.eclipse.net4j.tcp.TCPSelector; +import org.eclipse.net4j.tcp.TCPSelectorListener; +import org.eclipse.net4j.tcp.TCPSelectorListener.Active; +import org.eclipse.net4j.tcp.TCPSelectorListener.Passive; +import org.eclipse.net4j.util.lifecycle.LifecycleImpl; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.internal.net4j.bundle.Net4j; + +import java.io.IOException; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * @author Eike Stepper + */ +public class TCPSelectorImpl extends LifecycleImpl implements TCPSelector, Runnable +{ + private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_SELECTOR, TCPSelectorImpl.class); + + private Selector selector; + + private Queue<Runnable> pendingOperations = new ConcurrentLinkedQueue(); + + private Thread thread; + + public TCPSelectorImpl() + { + } + + public void invokeAsync(final Runnable operation) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Pending operation " + operation); + } + + pendingOperations.add(operation); + selector.wakeup(); + } + + public void registerAsync(final ServerSocketChannel channel, final Passive listener) + { + assertValidListener(listener); + invokeAsync(new Runnable() + { + public void run() + { + doRegister(channel, listener); + } + + @Override + public String toString() + { + return "REGISTER " + channel; + } + }); + } + + public void registerAsync(final SocketChannel channel, final Active listener) + { + assertValidListener(listener); + invokeAsync(new Runnable() + { + public void run() + { + doRegister(channel, listener); + } + + @Override + public String toString() + { + return "REGISTER " + channel; + } + }); + } + + public void setConnectInterest(final SelectionKey selectionKey, final boolean on) + { + invokeAsync(new Runnable() + { + public void run() + { + SelectorUtil.setConnectInterest(selectionKey, on); + } + + @Override + public String toString() + { + return "INTEREST CONNECT " + selectionKey + " = " + on; + } + }); + } + + public void setReadInterest(final SelectionKey selectionKey, final boolean on) + { + invokeAsync(new Runnable() + { + public void run() + { + SelectorUtil.setReadInterest(selectionKey, on); + } + + @Override + public String toString() + { + return "INTEREST READ " + selectionKey + " = " + on; + } + }); + } + + public void setWriteInterest(final SelectionKey selectionKey, final boolean on) + { + invokeAsync(new Runnable() + { + public void run() + { + SelectorUtil.setWriteInterest(selectionKey, on); + } + + @Override + public String toString() + { + return "INTEREST WRITE " + selectionKey + " = " + on; + } + + }); + } + + public void run() + { + while (isActive()) + { + if (Thread.interrupted()) + { + deactivate(); + break; + } + + try + { + Runnable operation; + while ((operation = pendingOperations.poll()) != null) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Executing operation " + operation); + } + + operation.run(); + } + + if (selector.select() > 0) + { + Iterator<SelectionKey> it = selector.selectedKeys().iterator(); + while (it.hasNext()) + { + SelectionKey selKey = it.next(); + it.remove(); + + try + { + handleSelection(selKey); + } + catch (CancelledKeyException ignore) + { + ; // Do nothing + } + catch (NullPointerException ignore) + { + ; // Do nothing + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + selKey.cancel(); + } + } + } + } + catch (ClosedSelectorException ex) + { + break; + } + catch (Exception ex) + { + Net4j.LOG.error(ex); + deactivate(); + break; + } + } + } + + @Override + public String toString() + { + return "TCPSelector"; //$NON-NLS-1$ + } + + protected void handleSelection(SelectionKey selKey) throws IOException + { + SelectableChannel channel = selKey.channel(); + if (channel instanceof ServerSocketChannel) + { + ServerSocketChannel ssChannel = (ServerSocketChannel)selKey.channel(); + TCPSelectorListener.Passive listener = (TCPSelectorListener.Passive)selKey.attachment(); + + if (selKey.isAcceptable()) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Accepting " + ssChannel); //$NON-NLS-1$ + } + + listener.handleAccept(this, ssChannel); + } + } + else if (channel instanceof SocketChannel) + { + SocketChannel sChannel = (SocketChannel)channel; + TCPSelectorListener.Active listener = (TCPSelectorListener.Active)selKey.attachment(); + + if (selKey.isConnectable()) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Connecting " + sChannel); //$NON-NLS-1$ + } + + listener.handleConnect(this, sChannel); + } + + if (selKey.isReadable()) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Reading " + sChannel); //$NON-NLS-1$ + } + + listener.handleRead(this, sChannel); + } + + if (selKey.isWritable()) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Writing " + sChannel); //$NON-NLS-1$ + } + + listener.handleWrite(this, sChannel); + } + } + } + + @Override + protected void onActivate() throws Exception + { + selector = Selector.open(); + thread = new Thread(this, "selector"); //$NON-NLS-1$ + thread.setDaemon(true); + thread.start(); + } + + @Override + protected void onDeactivate() throws Exception + { + selector.wakeup(); + Exception exception = null; + + try + { + thread.join(200); + } + catch (RuntimeException ex) + { + if (exception == null) + { + exception = ex; + } + } + finally + { + thread = null; + } + + try + { + selector.close(); + } + catch (Exception ex) + { + if (exception == null) + { + exception = ex; + } + } + finally + { + selector = null; + } + + if (exception != null) + { + throw exception; + } + } + + private void assertValidListener(Object listener) + { + if (listener == null) + { + throw new IllegalArgumentException("listener == null"); //$NON-NLS-1$ + } + } + + private void doRegister(final ServerSocketChannel channel, final TCPSelectorListener.Passive listener) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Registering " + channel); //$NON-NLS-1$ + } + + try + { + channel.register(selector, SelectionKey.OP_ACCEPT, listener); + } + catch (ClosedChannelException ignore) + { + ; + } + } + + private void doRegister(final SocketChannel channel, final TCPSelectorListener.Active listener) + { + if (TRACER.isEnabled()) + { + TRACER.trace("Registering " + channel); //$NON-NLS-1$ + } + + try + { + int interest = SelectionKey.OP_CONNECT | SelectionKey.OP_READ; + SelectionKey selectionKey = channel.register(selector, interest, listener); + listener.registered(selectionKey); + } + catch (ClosedChannelException ignore) + { + ; + } + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/Activator.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/Activator.java new file mode 100644 index 0000000000..40e631d43d --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/Activator.java @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp.bundle; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * @author Eike Stepper + */ +public class Activator implements BundleActivator +{ + public void start(BundleContext context) throws Exception + { + TCP.BUNDLE.setBundleContext(context); + } + + public void stop(BundleContext context) throws Exception + { + TCP.BUNDLE.setBundleContext(null); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/TCP.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/TCP.java new file mode 100644 index 0000000000..0f9dfb15cb --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/internal/tcp/bundle/TCP.java @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.internal.tcp.bundle; + +import org.eclipse.net4j.util.om.OMBundle; +import org.eclipse.net4j.util.om.OMLogger; +import org.eclipse.net4j.util.om.OMPlatform; +import org.eclipse.net4j.util.om.OMTracer; + +/** + * @author Eike Stepper + */ +public final class TCP +{ + public static final String BUNDLE_ID = "org.eclipse.net4j.tcp"; //$NON-NLS-1$ + + public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, TCP.class); + + public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$ + + public static final OMLogger LOG = BUNDLE.logger(); + + private TCP() + { + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPAcceptorFactory.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPAcceptorFactory.java new file mode 100644 index 0000000000..4b0cb68525 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPAcceptorFactory.java @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import org.eclipse.net4j.transport.AcceptorFactory; + +/** + * @author Eike Stepper + */ +public interface TCPAcceptorFactory extends AcceptorFactory +{ + public static final String TYPE = TCPContainerAdapter.TYPE; +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPConnectorFactory.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPConnectorFactory.java new file mode 100644 index 0000000000..412b44d80c --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPConnectorFactory.java @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import org.eclipse.net4j.transport.ConnectorFactory; + +/** + * @author Eike Stepper + */ +public interface TCPConnectorFactory extends ConnectorFactory +{ + public static final String TYPE = TCPContainerAdapter.TYPE; +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPContainerAdapter.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPContainerAdapter.java new file mode 100644 index 0000000000..b24d621d56 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPContainerAdapter.java @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import org.eclipse.net4j.transport.container.ContainerAdapter; + +/** + * @author Eike Stepper + */ +public interface TCPContainerAdapter extends ContainerAdapter +{ + public static final String TYPE = "TCP"; + + public TCPSelector getSelector(); +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelector.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelector.java new file mode 100644 index 0000000000..493eead36f --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelector.java @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import org.eclipse.net4j.tcp.TCPSelectorListener.Active; +import org.eclipse.net4j.tcp.TCPSelectorListener.Passive; + +import java.nio.channels.SelectionKey; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +/** + * @author Eike Stepper + */ +public interface TCPSelector +{ + public void invokeAsync(Runnable operation); + + public void registerAsync(ServerSocketChannel channel, Passive listener); + + public void registerAsync(SocketChannel channel, Active listener); + + public void setConnectInterest(SelectionKey selectionKey, boolean on); + + public void setReadInterest(SelectionKey selectionKey, boolean on); + + public void setWriteInterest(SelectionKey selectionKey, boolean on); +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelectorListener.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelectorListener.java new file mode 100644 index 0000000000..a83835f3bb --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPSelectorListener.java @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import java.nio.channels.SelectionKey; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +/** + * @author Eike Stepper + */ +public interface TCPSelectorListener +{ + /** + * @author Eike Stepper + */ + public interface Passive + { + public void handleAccept(TCPSelector selector, ServerSocketChannel serverSocketChannel); + } + + /** + * @author Eike Stepper + */ + public interface Active + { + public void registered(SelectionKey selectionKey); + + public void handleConnect(TCPSelector selector, SocketChannel channel); + + public void handleRead(TCPSelector selector, SocketChannel socketChannel); + + public void handleWrite(TCPSelector selector, SocketChannel socketChannel); + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPUtil.java b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPUtil.java new file mode 100644 index 0000000000..a7cccdd1cf --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/TCPUtil.java @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.tcp; + +import org.eclipse.internal.net4j.transport.DescriptionUtil; + +/** + * @author Eike Stepper + */ +public final class TCPUtil +{ + public static final String DEFAULT_ADDRESS = "0.0.0.0"; //$NON-NLS-1$ + + public static final int DEFAULT_PORT = 2036; + + private TCPUtil() + { + } + + public static String createAcceptorDescription() + { + return createAcceptorDescription(DEFAULT_ADDRESS); + } + + public static String createAcceptorDescription(String address) + { + return createAcceptorDescription(address, DEFAULT_PORT); + } + + public static String createAcceptorDescription(String address, int port) + { + Object[] elements = { address, port }; + return DescriptionUtil.getDescription(TCPContainerAdapter.TYPE, elements); + } + + public static String createConnectorDescription(String host) + { + return createConnectorDescription(host, null); + } + + public static String createConnectorDescription(String host, int port) + { + return createConnectorDescription(host, port, null); + } + + public static String createConnectorDescription(String host, String userName) + { + return createConnectorDescription(host, DEFAULT_PORT, userName); + } + + public static String createConnectorDescription(String host, int port, String userName) + { + Object[] elements = { host, port, userName }; + return DescriptionUtil.getDescription(TCPContainerAdapter.TYPE, elements); + } +} diff --git a/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/package.html b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/package.html new file mode 100644 index 0000000000..b2f6093963 --- /dev/null +++ b/plugins/org.eclipse.net4j.tcp/src/org/eclipse/net4j/tcp/package.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<!-- + + Copyright (c) 2004, 2005, 2006 Eike Stepper, Germany. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Contributors: + Eike Stepper - Initial API and implementation + +--> +</head> +<body bgcolor="white"> + +Interfaces for the transport layer specialized for TCP socket connections. +<p> + +<!-- + +<h2>Package Specification</h2> + +##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### +<ul> + <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> +</ul> + +<h2>Related Documentation</h2> + +For overviews, tutorials, examples, guides, and tool documentation, please see: +<ul> + <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> +</ul> + +--> + +<!-- Put @see and @since tags down here. --> + +</body> +</html> |