We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- using System;
- using System.Collections;
- using System.Net;
- using System.Net.Sockets;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Channels;
- using System.Threading;
- namespace System.Runtime.Remoting.Channels
- {
-
-
- internal delegate SocketHandler SocketHandlerFactory(Socket socket, SocketCache socketCache, string machineAndPort);
-
-
-
- internal class RemoteConnection
- {
- private static char[] colonSep = new char[] {':'};
-
- private CachedSocketList _cachedSocketList;
-
-
- private SocketCache _socketCache;
-
-
- private string _machineAndPort;
- private IPAddress[] _addressList;
- private int _port;
- private EndPoint _lkgIPEndPoint;
- private bool connectIPv6 = false;
-
-
- internal RemoteConnection(SocketCache socketCache, string machineAndPort)
- {
- _socketCache = socketCache;
-
- _cachedSocketList = new CachedSocketList(socketCache.SocketTimeout, socketCache.CachePolicy);
-
-
- Uri uri = new Uri("dummy://" + machineAndPort);
- string machineName = uri.Host;
- _port = uri.Port;
-
- _machineAndPort = machineAndPort;
-
- _addressList = Dns.GetHostAddresses(machineName);
- connectIPv6 = Socket.OSSupportsIPv6 && HasIPv6Address(_addressList);
- }
-
-
- internal SocketHandler GetSocket()
- {
-
- SocketHandler socketHandler = _cachedSocketList.GetSocket();
- if (socketHandler != null)
- return socketHandler;
-
-
- return CreateNewSocket();
- }
-
- internal void ReleaseSocket(SocketHandler socket)
- {
- socket.ReleaseControl();
- _cachedSocketList.ReturnSocket(socket);
- }
-
-
- private bool HasIPv6Address(IPAddress[] addressList)
- {
- foreach (IPAddress address in addressList) {
- if (address.AddressFamily == AddressFamily.InterNetworkV6)
- return true;
- }
- return false;
- }
-
- private void DisableNagleDelays(Socket socket)
- {
-
- socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
- }
-
- private SocketHandler CreateNewSocket()
- {
-
-
- if (_addressList.Length == 1)
- return CreateNewSocket(new IPEndPoint(_addressList[0], _port));
-
-
- if (_lkgIPEndPoint != null) {
- try {
- return CreateNewSocket(_lkgIPEndPoint);
- }
- catch (Exception) {
-
- _lkgIPEndPoint = null;
- }
- }
-
-
- if (connectIPv6) {
- try {
- return CreateNewSocket(AddressFamily.InterNetworkV6);
- }
- catch (Exception) {
- }
- }
-
-
- return CreateNewSocket(AddressFamily.InterNetwork);
-
- }
-
- private SocketHandler CreateNewSocket(EndPoint ipEndPoint)
- {
- Socket socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
- DisableNagleDelays(socket);
- InternalRemotingServices.RemotingTrace("RemoteConnection::CreateNewSocket: connecting new socket :: " + ipEndPoint);
-
- socket.Connect(ipEndPoint);
- _lkgIPEndPoint = socket.RemoteEndPoint;
- return _socketCache.CreateSocketHandler(socket, _machineAndPort);
- }
-
- private SocketHandler CreateNewSocket(AddressFamily family)
- {
- Socket socket = new Socket(family, SocketType.Stream, ProtocolType.Tcp);
-
- DisableNagleDelays(socket);
-
- socket.Connect(_addressList, _port);
- _lkgIPEndPoint = socket.RemoteEndPoint;
- return _socketCache.CreateSocketHandler(socket, _machineAndPort);
- }
-
-
- internal void TimeoutSockets(DateTime currentTime)
- {
- _cachedSocketList.TimeoutSockets(currentTime, _socketCache.SocketTimeout);
- }
-
-
-
- }
-
-
-
- internal class CachedSocket
- {
- private SocketHandler _socket;
- private DateTime _socketLastUsed;
-
- private CachedSocket _next;
-
- internal CachedSocket(SocketHandler socket, CachedSocket next)
- {
- _socket = socket;
- _socketLastUsed = DateTime.UtcNow;
- _next = next;
- }
-
- internal SocketHandler Handler {
- get { return _socket; }
- }
- internal DateTime LastUsed {
- get { return _socketLastUsed; }
- }
-
- internal CachedSocket Next {
- get { return _next; }
- set { _next = value; }
- }
-
- }
-
-
- internal class CachedSocketList
- {
- private int _socketCount;
- private TimeSpan _socketLifetime;
- private SocketCachePolicy _socketCachePolicy;
- private CachedSocket _socketList;
-
- internal CachedSocketList(TimeSpan socketLifetime, SocketCachePolicy socketCachePolicy)
- {
- _socketCount = 0;
- _socketLifetime = socketLifetime;
- _socketCachePolicy = socketCachePolicy;
- _socketList = null;
- }
-
-
- internal SocketHandler GetSocket()
- {
- if (_socketCount == 0)
- return null;
-
- lock (this) {
- if (_socketList != null) {
- SocketHandler socket = _socketList.Handler;
- _socketList = _socketList.Next;
-
- bool bRes = socket.RaceForControl();
-
-
-
- InternalRemotingServices.RemotingAssert(bRes, "someone else has the socket?");
-
- _socketCount--;
- return socket;
- }
- }
-
- return null;
- }
-
-
- internal void ReturnSocket(SocketHandler socket)
- {
- TimeSpan socketActiveTime = DateTime.UtcNow - socket.CreationTime;
- bool closeSocket = false;
- lock (this) {
-
-
- if (_socketCachePolicy != SocketCachePolicy.AbsoluteTimeout || socketActiveTime < _socketLifetime) {
-
- for (CachedSocket curr = _socketList; curr != null; curr = curr.Next) {
- if (socket == curr.Handler)
- return;
- }
-
- _socketList = new CachedSocket(socket, _socketList);
- _socketCount++;
- }
- else {
- closeSocket = true;
- }
- }
- if (closeSocket) {
- socket.Close();
- }
- }
-
-
- internal void TimeoutSockets(DateTime currentTime, TimeSpan socketLifetime)
- {
- lock (this) {
- CachedSocket prev = null;
- CachedSocket curr = _socketList;
-
- while (curr != null) {
-
-
-
- if ((_socketCachePolicy == SocketCachePolicy.AbsoluteTimeout && (currentTime - curr.Handler.CreationTime) > socketLifetime) || (currentTime - curr.LastUsed) > socketLifetime) {
- curr.Handler.Close();
-
-
- if (prev == null) {
-
- _socketList = curr.Next;
- curr = _socketList;
- }
- else {
-
- curr = curr.Next;
- prev.Next = curr;
- }
-
-
- _socketCount--;
- }
- else {
- prev = curr;
- curr = curr.Next;
- }
- }
- }
- }
-
-
- }
-
-
-
-
-
- internal class SocketCache
- {
-
- private static Hashtable _connections = new Hashtable();
-
- private SocketHandlerFactory _handlerFactory;
-
-
- private static RegisteredWaitHandle _registeredWaitHandle;
- private static WaitOrTimerCallback _socketTimeoutDelegate;
- private static AutoResetEvent _socketTimeoutWaitHandle;
- private static TimeSpan _socketTimeoutPollTime = TimeSpan.FromSeconds(10);
- private SocketCachePolicy _socketCachePolicy;
- private TimeSpan _socketTimeout;
- private int _receiveTimeout = 0;
-
-
- static SocketCache()
- {
- InitializeSocketTimeoutHandler();
- }
-
- internal SocketCache(SocketHandlerFactory handlerFactory, SocketCachePolicy socketCachePolicy, TimeSpan socketTimeout)
- {
- _handlerFactory = handlerFactory;
- _socketCachePolicy = socketCachePolicy;
- _socketTimeout = socketTimeout;
- }
-
- internal TimeSpan SocketTimeout {
- get { return _socketTimeout; }
- set { _socketTimeout = value; }
- }
- internal int ReceiveTimeout {
- get { return _receiveTimeout; }
- set { _receiveTimeout = value; }
- }
- internal SocketCachePolicy CachePolicy {
- get { return _socketCachePolicy; }
- set { _socketCachePolicy = value; }
- }
-
-
- private static void InitializeSocketTimeoutHandler()
- {
- _socketTimeoutDelegate = new WaitOrTimerCallback(TimeoutSockets);
- _socketTimeoutWaitHandle = new AutoResetEvent(false);
- _registeredWaitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject(_socketTimeoutWaitHandle, _socketTimeoutDelegate, "TcpChannelSocketTimeout", _socketTimeoutPollTime, true);
-
- }
-
- private static void TimeoutSockets(object state, bool wasSignalled)
- {
- DateTime currentTime = DateTime.UtcNow;
-
- lock (_connections) {
- foreach (DictionaryEntry entry in _connections) {
- RemoteConnection connection = (RemoteConnection)entry.Value;
- connection.TimeoutSockets(currentTime);
- }
- }
-
- _registeredWaitHandle.Unregister(null);
- _registeredWaitHandle = ThreadPool.UnsafeRegisterWaitForSingleObject(_socketTimeoutWaitHandle, _socketTimeoutDelegate, "TcpChannelSocketTimeout", _socketTimeoutPollTime, true);
-
- }
-
-
-
- internal SocketHandler CreateSocketHandler(Socket socket, string machineAndPort)
- {
- socket.ReceiveTimeout = _receiveTimeout;
- return _handlerFactory(socket, this, machineAndPort);
- }
-
-
-
- public SocketHandler GetSocket(string machinePortAndSid, bool openNew)
- {
- RemoteConnection connection = (RemoteConnection)_connections[machinePortAndSid];
- if (openNew || connection == null) {
- connection = new RemoteConnection(this, machinePortAndSid);
-
-
-
- lock (_connections) {
- _connections[machinePortAndSid] = connection;
- }
- }
-
- return connection.GetSocket();
- }
-
- public void ReleaseSocket(string machinePortAndSid, SocketHandler socket)
- {
- RemoteConnection connection = (RemoteConnection)_connections[machinePortAndSid];
- if (connection != null) {
- connection.ReleaseSocket(socket);
- }
- else {
-
-
- socket.Close();
- }
- }
-
-
- }
-
-
-
-
- }