summaryrefslogtreecommitdiff
path: root/cs/src/Ice/TcpTransceiver.cs
diff options
context:
space:
mode:
Diffstat (limited to 'cs/src/Ice/TcpTransceiver.cs')
-rw-r--r--cs/src/Ice/TcpTransceiver.cs211
1 files changed, 174 insertions, 37 deletions
diff --git a/cs/src/Ice/TcpTransceiver.cs b/cs/src/Ice/TcpTransceiver.cs
index c7210b1d37b..dab6897e12f 100644
--- a/cs/src/Ice/TcpTransceiver.cs
+++ b/cs/src/Ice/TcpTransceiver.cs
@@ -29,8 +29,23 @@ namespace IceInternal
{
try
{
+#if SILVERLIGHT
+ if(_writeEventArgs.SocketError != SocketError.Success)
+ {
+ SocketException ex = new SocketException((int)_writeEventArgs.SocketError);
+ if(Network.connectionRefused(ex))
+ {
+ throw new Ice.ConnectionRefusedException(ex);
+ }
+ else
+ {
+ throw new Ice.ConnectFailedException(ex);
+ }
+ }
+#else
Network.doFinishConnectAsync(_fd, _writeResult);
_writeResult = null;
+#endif
_state = StateConnected;
_desc = Network.fdToString(_fd);
}
@@ -88,9 +103,9 @@ namespace IceInternal
public bool write(Buffer buf)
{
-#if COMPACT
+#if COMPACT || SILVERLIGHT
//
- // The Compact Framework does not support the use of synchronous socket
+ // Silverlight and the Compact .NET Frameworks don't support the use of synchronous socket
// operations on a non-blocking socket. Returning false here forces the
// caller to schedule an asynchronous operation.
//
@@ -128,7 +143,7 @@ namespace IceInternal
{
ret = _fd.Send(buf.b.rawBytes(), buf.b.position(), packetSize, SocketFlags.None);
}
- catch(Win32Exception e)
+ catch(SocketException e)
{
if(Network.wouldBlock(e))
{
@@ -173,9 +188,9 @@ namespace IceInternal
public bool read(Buffer buf)
{
-#if COMPACT
+#if COMPACT || SILVERLIGHT
//
- // The .NET Compact Framework does not support the use of synchronous socket
+ // Silverlight and the Compact .NET Framework don't support the use of synchronous socket
// operations on a non-blocking socket.
//
return false;
@@ -211,7 +226,7 @@ namespace IceInternal
throw new Ice.ConnectionLostException();
}
}
- catch(Win32Exception e)
+ catch(SocketException e)
{
if(Network.wouldBlock(e))
{
@@ -236,7 +251,7 @@ namespace IceInternal
remaining -= ret;
buf.b.position(position += ret);
}
- catch(Win32Exception ex)
+ catch(SocketException ex)
{
//
// On Mono, calling shutdownReadWrite() followed by read() causes Socket.Receive() to
@@ -268,8 +283,13 @@ namespace IceInternal
public bool startRead(Buffer buf, AsyncCallback callback, object state)
{
+#if SILVERLIGHT
+ Debug.Assert(_fd != null && _readEventArgs != null);
+#else
Debug.Assert(_fd != null && _readResult == null);
+#endif
+#if !COMPACT && !SILVERLIGHT
// COMPILERFIX: Workaround for Mac OS X broken poll(), see Mono bug #470120
if(AssemblyUtil.osx_)
{
@@ -278,6 +298,7 @@ namespace IceInternal
Network.setBlock(_fd, true);
}
}
+#endif
int packetSize = buf.b.remaining();
if(_maxReceivePacketSize > 0 && packetSize > _maxReceivePacketSize)
@@ -287,10 +308,18 @@ namespace IceInternal
try
{
- _readResult = _fd.BeginReceive(buf.b.rawBytes(), buf.b.position(), packetSize, SocketFlags.None,
- callback, state);
+ _readCallback = callback;
+#if SILVERLIGHT
+ _readEventArgs.UserToken = state;
+ _readEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), packetSize);
+ return !_fd.ReceiveAsync(_readEventArgs);
+#else
+ _readResult = _fd.BeginReceive(buf.b.rawBytes(), buf.b.position(), packetSize, SocketFlags.None,
+ readCompleted, state);
+ return _readResult.CompletedSynchronously;
+#endif
}
- catch(Win32Exception ex)
+ catch(SocketException ex)
{
if(Network.connectionLost(ex))
{
@@ -299,29 +328,43 @@ namespace IceInternal
throw new Ice.SocketException(ex);
}
-
- return _readResult.CompletedSynchronously;
}
public void finishRead(Buffer buf)
{
if(_fd == null) // Transceiver was closed
+#if SILVERLIGHT
+ {
+ _readEventArgs = null;
+ return;
+ }
+ Debug.Assert(_fd != null && _readEventArgs != null);
+#else
{
_readResult = null;
return;
}
-
Debug.Assert(_fd != null && _readResult != null);
+#endif
try
{
+#if SILVERLIGHT
+ if(_readEventArgs.SocketError != SocketError.Success)
+ {
+ throw new SocketException((int)_readEventArgs.SocketError);
+ }
+ int ret = _readEventArgs.BytesTransferred;
+#else
int ret = _fd.EndReceive(_readResult);
_readResult = null;
+#endif
if(ret == 0)
{
throw new Ice.ConnectionLostException();
}
+#if !COMPACT && !SILVERLIGHT
// COMPILERFIX: Workaround for Mac OS X broken poll(), see Mono bug #470120
if(AssemblyUtil.osx_)
{
@@ -330,6 +373,7 @@ namespace IceInternal
Network.setBlock(_fd, false);
}
}
+#endif
Debug.Assert(ret > 0);
if(_traceLevels.network >= 3)
@@ -350,7 +394,7 @@ namespace IceInternal
buf.b.position(buf.b.position() + ret);
}
- catch(Win32Exception ex)
+ catch(SocketException ex)
{
if(Network.connectionLost(ex))
{
@@ -367,8 +411,13 @@ namespace IceInternal
public bool startWrite(Buffer buf, AsyncCallback callback, object state, out bool completed)
{
+#if SILVERLIGHT
+ Debug.Assert(_fd != null && _writeEventArgs != null);
+#else
Debug.Assert(_fd != null && _writeResult == null);
+#endif
+#if !COMPACT && !SILVERLIGHT
// COMPILERFIX: Workaround for Mac OS X broken poll(), see Mono bug #470120
if(AssemblyUtil.osx_)
{
@@ -377,12 +426,19 @@ namespace IceInternal
Network.setBlock(_fd, true);
}
}
+#endif
if(_state < StateConnected)
{
- _writeResult = Network.doConnectAsync(_fd, _addr, callback, state);
completed = false;
+ _writeCallback = callback;
+#if SILVERLIGHT
+ _writeEventArgs.UserToken = state;
+ return !_fd.ConnectAsync(_writeEventArgs);
+#else
+ _writeResult = Network.doConnectAsync(_fd, _addr, callback, state);
return _writeResult.CompletedSynchronously;
+#endif
}
//
@@ -397,10 +453,20 @@ namespace IceInternal
try
{
+ _writeCallback = callback;
+#if SILVERLIGHT
+ _writeEventArgs.UserToken = state;
+ _writeEventArgs.SetBuffer(buf.b.rawBytes(), buf.b.position(), packetSize);
+ bool completedSynchronously = !_fd.SendAsync(_writeEventArgs);
+#else
_writeResult = _fd.BeginSend(buf.b.rawBytes(), buf.b.position(), packetSize, SocketFlags.None,
- callback, state);
+ writeCompleted, state);
+ bool completedSynchronously = _writeResult.CompletedSynchronously;
+#endif
+ completed = packetSize == buf.b.remaining();
+ return completedSynchronously;
}
- catch(Win32Exception ex)
+ catch(SocketException ex)
{
if(Network.connectionLost(ex))
{
@@ -413,9 +479,6 @@ namespace IceInternal
{
throw new Ice.ConnectionLostException(ex);
}
-
- completed = packetSize == buf.b.remaining();
- return _writeResult.CompletedSynchronously;
}
public void finishWrite(Buffer buf)
@@ -426,11 +489,19 @@ namespace IceInternal
{
buf.b.position(buf.size()); // Assume all the data was sent for at-most-once semantics.
}
+#if SILVERLIGHT
+ _writeEventArgs = null;
+#else
_writeResult = null;
+#endif
return;
}
+#if SILVERLIGHT
+ Debug.Assert(_fd != null && _writeEventArgs != null);
+#else
Debug.Assert(_fd != null && _writeResult != null);
+#endif
if(_state < StateConnected)
{
@@ -439,14 +510,23 @@ namespace IceInternal
try
{
+#if SILVERLIGHT
+ if(_writeEventArgs.SocketError != SocketError.Success)
+ {
+ throw new SocketException((int)_writeEventArgs.SocketError);
+ }
+ int ret = _writeEventArgs.BytesTransferred;
+#else
int ret = _fd.EndSend(_writeResult);
_writeResult = null;
+#endif
if(ret == 0)
{
throw new Ice.ConnectionLostException();
}
Debug.Assert(ret > 0);
+#if !COMPACT && !SILVERLIGHT
// COMPILERFIX: Workaround for Mac OS X broken poll(), see Mono bug #470120
if(AssemblyUtil.osx_)
{
@@ -455,6 +535,7 @@ namespace IceInternal
Network.setBlock(_fd, false);
}
}
+#endif
if(_traceLevels.network >= 3)
{
@@ -474,7 +555,7 @@ namespace IceInternal
buf.b.position(buf.b.position() + ret);
}
- catch(Win32Exception ex)
+ catch(SocketException ex)
{
if(Network.connectionLost(ex))
{
@@ -499,20 +580,12 @@ namespace IceInternal
{
Debug.Assert(_fd != null);
Ice.TCPConnectionInfo info = new Ice.TCPConnectionInfo();
- IPEndPoint localEndpoint = Network.getLocalAddress(_fd);
- info.localAddress = localEndpoint.Address.ToString();
- info.localPort = localEndpoint.Port;
- IPEndPoint remoteEndpoint = Network.getRemoteAddress(_fd);
- if(remoteEndpoint != null)
- {
- info.remoteAddress = remoteEndpoint.Address.ToString();
- info.remotePort = remoteEndpoint.Port;
- }
- else
- {
- info.remoteAddress = "";
- info.remotePort = -1;
- }
+ EndPoint localEndpoint = Network.getLocalAddress(_fd);
+ info.localAddress = Network.endpointAddressToString(localEndpoint);
+ info.localPort = Network.endpointPort(localEndpoint);
+ EndPoint remoteEndpoint = Network.getRemoteAddress(_fd);
+ info.remoteAddress = Network.endpointAddressToString(remoteEndpoint);
+ info.remotePort = Network.endpointPort(remoteEndpoint);
return info;
}
@@ -532,10 +605,29 @@ namespace IceInternal
//
// Only for use by TcpConnector, TcpAcceptor
//
- internal TcpTransceiver(Instance instance, Socket fd, IPEndPoint addr, bool connected)
+ internal TcpTransceiver(Instance instance, Socket fd, EndPoint addr, bool connected)
{
_fd = fd;
_addr = addr;
+
+#if SILVERLIGHT
+ _readEventArgs = new SocketAsyncEventArgs();
+ if(instance.initializationData().properties.getProperty("Ice.ClientAccessPolicyProtocol").Equals("Http"))
+ {
+ _readEventArgs.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http;
+ }
+ _readEventArgs.RemoteEndPoint = _addr;
+ _readEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
+
+ _writeEventArgs = new SocketAsyncEventArgs();
+ if(instance.initializationData().properties.getProperty("Ice.ClientAccessPolicyProtocol").Equals("Http"))
+ {
+ _writeEventArgs.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http;
+ }
+ _writeEventArgs.RemoteEndPoint = _addr;
+ _writeEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ioCompleted);
+#endif
+
_traceLevels = instance.traceLevels();
_logger = instance.initializationData().logger;
_stats = instance.initializationData().stats;
@@ -555,8 +647,42 @@ namespace IceInternal
}
}
+#if SILVERLIGHT
+ internal void ioCompleted(object sender, SocketAsyncEventArgs e)
+ {
+ switch (e.LastOperation)
+ {
+ case SocketAsyncOperation.Receive:
+ _readCallback(e.UserToken);
+ break;
+ case SocketAsyncOperation.Send:
+ case SocketAsyncOperation.Connect:
+ _writeCallback(e.UserToken);
+ break;
+ default:
+ throw new ArgumentException("The last operation completed on the socket was not a receive or send");
+ }
+ }
+#else
+ internal void readCompleted(IAsyncResult result)
+ {
+ if(!result.CompletedSynchronously)
+ {
+ _readCallback(result.AsyncState);
+ }
+ }
+
+ internal void writeCompleted(IAsyncResult result)
+ {
+ if(!result.CompletedSynchronously)
+ {
+ _writeCallback(result.AsyncState);
+ }
+ }
+#endif
+
private Socket _fd;
- private IPEndPoint _addr;
+ private EndPoint _addr;
private TraceLevels _traceLevels;
private Ice.Logger _logger;
private Ice.Stats _stats;
@@ -565,9 +691,20 @@ namespace IceInternal
private int _maxSendPacketSize;
private int _maxReceivePacketSize;
+#if !COMPACT && !SILVERLIGHT
private int _blocking = 0;
+#endif
+
+#if SILVERLIGHT
+ private SocketAsyncEventArgs _writeEventArgs;
+ private SocketAsyncEventArgs _readEventArgs;
+#else
private IAsyncResult _writeResult;
private IAsyncResult _readResult;
+#endif
+
+ AsyncCallback _writeCallback;
+ AsyncCallback _readCallback;
private const int StateNeedConnect = 0;
private const int StateConnectPending = 1;