summaryrefslogtreecommitdiff
path: root/java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java
diff options
context:
space:
mode:
Diffstat (limited to 'java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java')
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java329
1 files changed, 329 insertions, 0 deletions
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java b/java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java
new file mode 100644
index 00000000000..03cd265e0e6
--- /dev/null
+++ b/java-compat/src/Ice/src/main/java/IceInternal/StreamSocket.java
@@ -0,0 +1,329 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceInternal;
+
+public class StreamSocket
+{
+ public StreamSocket(ProtocolInstance instance,
+ NetworkProxy proxy,
+ java.net.InetSocketAddress addr,
+ java.net.InetSocketAddress sourceAddr)
+ {
+ _instance = instance;
+ _proxy = proxy;
+ _addr = addr;
+ _fd = Network.createTcpSocket();
+ _state = StateNeedConnect;
+
+ try
+ {
+ init();
+ if(Network.doConnect(_fd, _proxy != null ? _proxy.getAddress() : _addr, sourceAddr))
+ {
+ _state = _proxy != null ? StateProxyWrite : StateConnected;
+ }
+ }
+ catch(Ice.LocalException ex)
+ {
+ assert(!_fd.isOpen());
+ _fd = null; // Necessary for the finalizer
+ throw ex;
+ }
+
+ _desc = Network.fdToString(_fd, _proxy, _addr);
+ }
+
+ public StreamSocket(ProtocolInstance instance, java.nio.channels.SocketChannel fd)
+ {
+ _instance = instance;
+ _proxy = null;
+ _addr = null;
+ _fd = fd;
+ _state = StateConnected;
+
+ try
+ {
+ init();
+ }
+ catch(Ice.LocalException ex)
+ {
+ assert(!_fd.isOpen());
+ _fd = null; // Necessary for the finalizer
+ throw ex;
+ }
+
+ _desc = Network.fdToString(_fd);
+ }
+
+ @Override
+ protected synchronized void finalize()
+ throws Throwable
+ {
+ try
+ {
+ IceUtilInternal.Assert.FinalizerAssert(_fd == null);
+ }
+ catch(java.lang.Exception ex)
+ {
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+
+ public void setBufferSize(int rcvSize, int sndSize)
+ {
+ Network.setTcpBufSize(_fd, rcvSize, sndSize, _instance);
+ }
+
+ public int connect(Buffer readBuffer, Buffer writeBuffer)
+ {
+ if(_state == StateNeedConnect)
+ {
+ _state = StateConnectPending;
+ return SocketOperation.Connect;
+ }
+ else if(_state <= StateConnectPending)
+ {
+ Network.doFinishConnect(_fd);
+ _desc = Network.fdToString(_fd, _proxy, _addr);
+ _state = _proxy != null ? StateProxyWrite : StateConnected;
+ }
+
+ if(_state == StateProxyWrite)
+ {
+ _proxy.beginWrite(_addr, writeBuffer);
+ return SocketOperation.Write;
+ }
+ else if(_state == StateProxyRead)
+ {
+ _proxy.beginRead(readBuffer);
+ return SocketOperation.Read;
+ }
+ else if(_state == StateProxyConnected)
+ {
+ _proxy.finish(readBuffer, writeBuffer);
+
+ readBuffer.clear();
+ writeBuffer.clear();
+
+ _state = StateConnected;
+ }
+
+ assert(_state == StateConnected);
+ return SocketOperation.None;
+ }
+
+ public boolean isConnected()
+ {
+ return _state == StateConnected;
+ }
+
+ public java.nio.channels.SocketChannel fd()
+ {
+ return _fd;
+ }
+
+ public int read(Buffer buf)
+ {
+ if(_state == StateProxyRead)
+ {
+ while(true)
+ {
+ int ret = read(buf.b);
+ if(ret == 0)
+ {
+ return SocketOperation.Read;
+ }
+ _state = toState(_proxy.endRead(buf));
+ if(_state != StateProxyRead)
+ {
+ return SocketOperation.None;
+ }
+ }
+ }
+ read(buf.b);
+ return buf.b.hasRemaining() ? SocketOperation.Read : SocketOperation.None;
+ }
+
+ public int write(Buffer buf)
+ {
+ if(_state == StateProxyWrite)
+ {
+ while(true)
+ {
+ int ret = write(buf.b);
+ if(ret == 0)
+ {
+ return SocketOperation.Write;
+ }
+ _state = toState(_proxy.endWrite(buf));
+ if(_state != StateProxyWrite)
+ {
+ return SocketOperation.None;
+ }
+ }
+ }
+ write(buf.b);
+ return buf.b.hasRemaining() ? SocketOperation.Write : SocketOperation.None;
+ }
+
+ public int read(java.nio.ByteBuffer buf)
+ {
+ assert(_fd != null);
+
+ int read = 0;
+
+ while(buf.hasRemaining())
+ {
+ try
+ {
+ int ret = _fd.read(buf);
+ if(ret == -1)
+ {
+ throw new Ice.ConnectionLostException();
+ }
+ else if(ret == 0)
+ {
+ return read;
+ }
+
+ read += ret;
+ }
+ catch(java.io.InterruptedIOException ex)
+ {
+ continue;
+ }
+ catch(java.io.IOException ex)
+ {
+ throw new Ice.ConnectionLostException(ex);
+ }
+ }
+ return read;
+ }
+
+ public int write(java.nio.ByteBuffer buf)
+ {
+ assert(_fd != null);
+
+ int sent = 0;
+ while(buf.hasRemaining())
+ {
+ try
+ {
+ int ret;
+ if(_maxSendPacketSize > 0 && buf.remaining() > _maxSendPacketSize)
+ {
+ int previous = buf.limit();
+ buf.limit(buf.position() + _maxSendPacketSize);
+ ret = _fd.write(buf);
+ buf.limit(previous);
+ }
+ else
+ {
+ ret = _fd.write(buf);
+ }
+
+ if(ret == -1)
+ {
+ throw new Ice.ConnectionLostException();
+ }
+ else if(ret == 0)
+ {
+ return sent;
+ }
+ sent += ret;
+ }
+ catch(java.io.InterruptedIOException ex)
+ {
+ continue;
+ }
+ catch(java.io.IOException ex)
+ {
+ throw new Ice.SocketException(ex);
+ }
+ }
+ return sent;
+ }
+
+ public void close()
+ {
+ assert(_fd != null);
+ try
+ {
+ _fd.close();
+ }
+ catch(java.io.IOException ex)
+ {
+ throw new Ice.SocketException(ex);
+ }
+ finally
+ {
+ _fd = null;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return _desc;
+ }
+
+ private void init()
+ {
+ Network.setBlock(_fd, false);
+ Network.setTcpBufSize(_fd, _instance);
+
+ if(System.getProperty("os.name").startsWith("Windows"))
+ {
+ //
+ // On Windows, limiting the buffer size is important to prevent
+ // poor throughput performances when sending large amount of
+ // data. See Microsoft KB article KB823764.
+ //
+ _maxSendPacketSize = java.lang.Math.max(512, Network.getSendBufferSize(_fd) / 2);
+ }
+ else
+ {
+ _maxSendPacketSize = 0;
+ }
+ }
+
+ private int toState(int operation)
+ {
+ switch(operation)
+ {
+ case SocketOperation.Read:
+ return StateProxyRead;
+ case SocketOperation.Write:
+ return StateProxyWrite;
+ default:
+ return StateProxyConnected;
+ }
+ }
+
+ private final ProtocolInstance _instance;
+
+ final private NetworkProxy _proxy;
+ final private java.net.InetSocketAddress _addr;
+
+ private java.nio.channels.SocketChannel _fd;
+ private int _maxSendPacketSize;
+ private int _state;
+ private String _desc;
+
+ private static final int StateNeedConnect = 0;
+ private static final int StateConnectPending = 1;
+ private static final int StateProxyRead = 2;
+ private static final int StateProxyWrite = 3;
+ private static final int StateProxyConnected = 4;
+ private static final int StateConnected = 5;
+}