diff options
Diffstat (limited to 'plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/core/ChannelTCP.java')
-rw-r--r-- | plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/core/ChannelTCP.java | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/core/ChannelTCP.java b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/core/ChannelTCP.java new file mode 100644 index 000000000..a9dcbfdd3 --- /dev/null +++ b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/core/ChannelTCP.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tm.tcf.core; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; + +import org.eclipse.tm.tcf.protocol.IPeer; +import org.eclipse.tm.tcf.protocol.Protocol; + +/** + * ChannelTCP is a IChannel implementation that works on top of TCP sockets as a transport. + */ +public class ChannelTCP extends StreamChannel { + + private Socket socket; + private int timeout; + private InputStream inp; + private OutputStream out; + private boolean started; + private boolean closed; + + private static SSLContext ssl_context; + + public static void setSSLContext(SSLContext ssl_context) { + ChannelTCP.ssl_context = ssl_context; + } + + public ChannelTCP(IPeer remote_peer, final String host, final int port, final boolean ssl) { + super(remote_peer); + socket = new Socket(); + Protocol.invokeLater(new Runnable() { + public void run() { + Thread thread = new Thread() { + public void run() { + try { + socket.connect(new InetSocketAddress(host, port), timeout); + socket.setTcpNoDelay(true); + socket.setKeepAlive(true); + if (ssl) { + if (ssl_context == null) throw new Exception("SSL context is not set"); + socket = ssl_context.getSocketFactory().createSocket(socket, host, port, true); + ((SSLSocket)socket).startHandshake(); + } + inp = new BufferedInputStream(socket.getInputStream()); + out = new BufferedOutputStream(socket.getOutputStream()); + onSocketConnected(null); + } + catch (Exception x) { + onSocketConnected(x); + } + } + }; + thread.setName("TCF Socket Connect"); + thread.start(); + } + }); + } + + public ChannelTCP(IPeer remote_peer, String host, int port) { + this(remote_peer, host, port, false); + } + + public ChannelTCP(IPeer local_peer, IPeer remote_peer, Socket socket) throws IOException { + super(local_peer, remote_peer); + this.socket = socket; + socket.setTcpNoDelay(true); + socket.setKeepAlive(true); + inp = new BufferedInputStream(socket.getInputStream()); + out = new BufferedOutputStream(socket.getOutputStream()); + onSocketConnected(null); + } + + public void setConnectTimeout(int timeout) { + this.timeout = timeout; + } + + public void setReuseAddress(boolean on) throws SocketException { + socket.setReuseAddress(on); + } + + public void setReceiveBufferSize(int size) throws SocketException{ + socket.setReceiveBufferSize(size); + } + + public void setSendBufferSize(int size) throws SocketException{ + socket.setSendBufferSize(size); + } + + public void setSoLinger(boolean on, int linger) throws SocketException { + socket.setSoLinger(on, linger); + } + + public void setTrafficClass(int tc) throws SocketException { + socket.setTrafficClass(tc); + } + + public void setPerformancePreferences(int connection_time, int latency, int bandwidth) { + socket.setPerformancePreferences(connection_time, latency, bandwidth); + } + + private void onSocketConnected(final Throwable x) { + Protocol.invokeLater(new Runnable() { + public void run() { + if (x != null) { + terminate(x); + closed = true; + } + if (closed) { + try { + if (socket != null) { + socket.close(); + if (out != null) out.close(); + if (inp != null) inp.close(); + } + } + catch (IOException y) { + Protocol.log("Cannot close socket", y); + } + } + else { + started = true; + start(); + } + } + }); + } + + @Override + protected final int get() throws IOException { + try { + if (closed) return -1; + return inp.read(); + } + catch (IOException x) { + if (closed) return -1; + throw x; + } + } + + @Override + protected final int get(byte[] buf) throws IOException { + try { + if (closed) return -1; + return inp.read(buf); + } + catch (IOException x) { + if (closed) return -1; + throw x; + } + } + + @Override + protected final void put(int b) throws IOException { + assert b >= 0 && b <= 0xff; + if (closed) return; + out.write(b); + } + + @Override + protected final void put(byte[] buf) throws IOException { + if (closed) return; + out.write(buf); + } + + @Override + protected final void flush() throws IOException { + if (closed) return; + out.flush(); + } + + @Override + protected void stop() throws IOException { + closed = true; + if (started) { + socket.close(); + out.close(); + inp.close(); + } + } +} |