Beispiel #1
0
        /// <summary>
        /// Called by XmlSerializationSectionHandler when the config is reloaded.
        /// </summary>
        public void ReloadConfig(object sender, EventArgs args)
        {
            SocketClientConfig newConfig = GetConfig();

            if (mySettings == defaultMessageSettings)                                //current using defaults, if defaults change we want to change the active socket pool
            {
                if (!newConfig.DefaultSocketSettings.SameAs(defaultMessageSettings)) //settings have changed, need to change "mySocketPool(s)" reference
                {
                    if (log.IsInfoEnabled)
                    {
                        log.Info("Default socket settings changed, updating default socket pool.");
                    }

                    mySocketPools = SocketManager.Instance.GetSocketPools(newConfig.DefaultSocketSettings);
                    if (mySocketPool != null && myEndPoint != null)
                    {
                        SocketPool oldDefault = mySocketPool;
                        mySocketPool = GetSocketPool(myEndPoint, newConfig.DefaultSocketSettings);
                        oldDefault.ReleaseAndDisposeAll();
                    }
                }
                mySettings = newConfig.DefaultSocketSettings;
            }

            defaultMessageSettings = newConfig.DefaultSocketSettings;
            config = newConfig;
        }
Beispiel #2
0
        private void SendOneWay(SocketPool pool, int commandID, MemoryStream messageStream)
        {
            ManagedSocket socket = null;
            ResourcePoolItem <MemoryStream> rebufferedStreamItem = CreateOneWayMessage(commandID, messageStream, pool);

            try
            {
                MemoryStream rebufferedStream = rebufferedStreamItem.Item;
                socket = pool.GetSocket();
                // GetBuffer() should be used in preference to ToArray() where possible
                // as it does not allocate a new byte[] like ToArray does().
                byte[] messageBuffer = rebufferedStream.GetBuffer();
                socket.Send(messageBuffer, (int)rebufferedStream.Length, SocketFlags.None);
            }
            catch (SocketException sex)
            {
                if (socket != null)
                {
                    socket.LastError = sex.SocketErrorCode;
                }
                throw;
            }
            finally
            {
                if (socket != null)
                {
                    socket.Release();
                }
                rebufferedStreamItem.Release();
            }
        }
Beispiel #3
0
        private static void SendOneWay(SocketPool pool, int commandID, MemoryStream messageStream)
        {
            ManagedSocket socket = null;
            ResourcePoolItem <MemoryStream> rebufferedStreamItem = CreateOneWayMessage(commandID, messageStream, pool);

            try
            {
                MemoryStream rebufferedStream = rebufferedStreamItem.Item;
                socket = pool.GetSocket();
                // GetBuffer() should be used in preference to ToArray() where possible
                // as it does not allocate a new byte[] like ToArray does().
                byte[] messageBuffer = rebufferedStream.GetBuffer();

                socket.Send(messageBuffer, (int)rebufferedStream.Length, SocketFlags.None);
                if (socket.ServerSupportsAck && pool.Settings.RequestOneWayAck)
                {
                    try
                    {
                        socket.GetReply();                         //make sure we got the ack
                    }
                    catch (SocketException sex)
                    {
                        log.ErrorFormat("Failed to receive ack from {0} with error {1}", pool.Destination, sex.SocketErrorCode);
                        throw;
                    }
                }
                catch (Exception ex)
                {
                    log.ErrorFormat("Failed to receive ack from {0} with error {1}", pool.Destination, ex.Message);
                    throw;
                }
            }
        internal void GetSocketCounts(IPEndPoint destination, SocketSettings settings, out int totalSockets, out int activeSockets)
        {
            SocketPool pool = GetSocketPool(destination, settings);

            activeSockets = pool.activeSocketCount;
            totalSockets  = pool.socketCount;
        }
Beispiel #5
0
        /// <summary>
        /// Sends a message to a server that does not expect a reply.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="messageSettings">Settings for the transport.</param>
        /// <param name="commandID">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        public void SendOneWay(IPEndPoint destination, SocketSettings messageSettings, int commandID, MemoryStream messageStream)
        {
            //we have both destination and settings so just use them
            SocketPool socketPool = SocketManager.Instance.GetSocketPool(destination, messageSettings);

            SendOneWay(socketPool, commandID, messageStream);
        }
Beispiel #6
0
        /// <summary>
        /// Sends a message to the server that expects a response.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="messageSettings">The settings to use for the transport.</param>
        /// <param name="commandID">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        /// <returns>The object returned by the server, if any.</returns>
        public MemoryStream SendSync(IPEndPoint destination, SocketSettings messageSettings, int commandID, MemoryStream messageStream)
        {
            SocketPool   pool        = SocketManager.Instance.GetSocketPool(destination, messageSettings);
            MemoryStream replyStream = SendSync(pool, commandID, messageStream);

            return(replyStream);
        }
Beispiel #7
0
 /// <summary>
 /// Create a new SocketClient with a default connection to destination, using the supplied settings.
 /// </summary>
 public SocketClient(IPEndPoint destination, SocketSettings settings)
 {
     LoadConfig();
     mySettings         = settings;
     myEndPoint         = destination;
     this.mySocketPools = SocketManager.Instance.GetSocketPools(settings);
     this.mySocketPool  = GetSocketPool(destination, settings);
 }
		/// <summary>
		/// Create a new SocketClient with a default connection to destination, using the supplied settings.
		/// </summary>		
		public SocketClient(IPEndPoint destination, SocketSettings settings)
		{
			LoadConfig();
			mySettings = settings;
			myEndPoint = destination;
			this.mySocketPools = SocketManager.Instance.GetSocketPools(settings);
			this.mySocketPool = GetSocketPool(destination, settings);
		}
Beispiel #9
0
 /// <summary>
 /// Create a new SocketClient with a default connection to destination, using the default settings.
 /// </summary>
 public SocketClient(IPEndPoint destination)
 {
     //ideally if the default settings are changed, then this reference should be as well
     //but there is no way to do this without a delegate, and previous users of socket client
     //can't be expected to start using a dispose method, so this functionality will have to
     //not exist.
     mySocketPool = SocketManager.Instance.GetSocketPool(destination);
 }
Beispiel #10
0
        /// <summary>
        /// Sends a message to a server that does not expect a reply using the process wide default message settings.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="commandId">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        public static void SendOneWayDefault(IPEndPoint destination, int commandId, MemoryStream messageStream)
        {
            //we have the destination, we want to use any settings supplied at instantiation, or if none were
            //supplied then, the defaults

            SocketPool socketPool = SocketManager.Instance.GetSocketPool(destination);

            SendOneWay(socketPool, commandId, messageStream);
        }
        /// <summary>
        ///     <para>Initializes a new instance of the <see cref="AsyncSocketClient"/> class.</para>
        /// </summary>
        /// <param name="endPoint">The remote end-point this instance will connect to.</param>
        /// <param name="config">Optional configuration settings. Specify <see langword="null"/> to fallback on reasonable defaults.</param>
        /// <exception cref="ArgumentNullException">
        ///	<para><paramref name="endPoint"/> is <see langword="null"/>.</para>
        /// </exception>
        public AsyncSocketClient(IPEndPoint endPoint, SocketPoolConfig config)
        {
            if (endPoint == null)
            {
                throw new ArgumentNullException("endPoint");
            }

            _socketPool = new SocketPool(endPoint, config ?? new SocketPoolConfig());
        }
Beispiel #12
0
        /// <summary>
        /// Sends a message to the server that expects a response, using the default message settings.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="commandID">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        /// <returns>The object returned by the server, if any.</returns>
        public MemoryStream SendSync(IPEndPoint destination, int commandID, MemoryStream messageStream)
        {
            MemoryStream replyStream = null;
            SocketPool   socketPool  = GetSocketPool(destination);

            replyStream = SendSync(socketPool, commandID, messageStream);


            return(replyStream);
        }
Beispiel #13
0
 internal ManagedSocket(SocketSettings settings, SocketPool socketPool)
     : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
 {
     CreatedTicks = DateTime.UtcNow.Ticks;
     SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, settings.SendBufferSize);
     SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, settings.ReceiveBufferSize);
     SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, settings.SendTimeout);
     SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, settings.ReceiveTimeout);
     SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
     _settings = settings;
     myPool    = socketPool;
 }
Beispiel #14
0
 internal ManagedSocket(SocketSettings settings, SocketPool socketPool)
     : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
 {
     this.CreatedTicks = DateTime.UtcNow.Ticks;
     this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, settings.SendBufferSize);
     this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, settings.ReceiveBufferSize);
     this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, settings.SendTimeout);
     this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, settings.ReceiveTimeout);
     this.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
     this.settings       = settings;
     buildSocketCallBack = new AsyncCallback(BuildSocketCallBack);
     receiveCallBack     = new AsyncCallback(ReceiveCallback);
     this.myPool         = socketPool;
 }
		internal ManagedSocket(SocketSettings settings, SocketPool socketPool)
			: base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
		{
			this.CreatedTicks = DateTime.UtcNow.Ticks;
			this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, settings.SendBufferSize);
			this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, settings.ReceiveBufferSize);
			this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, settings.SendTimeout);
			this.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, settings.ReceiveTimeout);
			this.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
			this.settings = settings;
			buildSocketCallBack = new AsyncCallback(BuildSocketCallBack);
			receiveCallBack = new AsyncCallback(ReceiveCallback);
			this.myPool = socketPool;
		}
Beispiel #16
0
        private MemoryStream SendSync(SocketPool pool, int commandID, MemoryStream messageStream)
        {
            short messageId = (short)1;             //new async scheme doesn't currently need these.
            ResourcePoolItem <MemoryStream> rebufferedStreamItem = CreateSyncMessage((short)commandID, messageId, messageStream, pool);
            MemoryStream rebufferedStream = rebufferedStreamItem.Item;

            ManagedSocket socket      = null;
            MemoryStream  replyStream = null;

            try
            {
                socket = pool.GetSocket();

                // GetBuffer() should be used in preference to ToArray() where possible
                // as it does not allocate a new byte[] like ToArray does().
                socket.Send(rebufferedStream.GetBuffer(), (int)rebufferedStream.Length, SocketFlags.None);
                replyStream = socket.GetReply();
            }
            catch (ThreadAbortException)
            {
                if (socket != null)
                {
                    socket.LastError = SocketError.TimedOut;
                }
                log.Warn("Thread aborted on SocketClient.");
                throw;
            }
            catch (SocketException ex)
            {
                if (socket != null)
                {
                    socket.LastError = ex.SocketErrorCode;
                }
                throw;
            }
            finally
            {
                rebufferedStreamItem.Release();
                if (socket != null)                 //getting the socket can throw a timedout exception due to limiting, in which case the socket will be null
                {
                    socket.Release();
                }
            }

            return(replyStream);
        }
		internal ArrayManagedSocket(SocketSettings settings, SocketPool pool, int index)
			: base(settings, pool)
		{
			this.Index = index;
		}		
Beispiel #18
0
        /// <summary>
        /// Sends a message to a server that does not expect a reply using the default message settings.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="commandId">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        public void SendOneWay(IPEndPoint destination, int commandId, MemoryStream messageStream)
        {
            SocketPool socketPool = GetSocketPool(destination);

            SendOneWay(socketPool, commandId, messageStream);
        }
		/// <summary>
		/// Create a new SocketClient with a default connection to destination, using the default settings.
		/// </summary>		
		public SocketClient(IPEndPoint destination)
			: this()
		{
			myEndPoint = destination;
			mySocketPool = GetSocketPool(destination);
		}
		private ResourcePoolItem<MemoryStream> CreateMessage(short commandId, short messageId, MemoryStream messageStream, bool isSync, SocketPool pool)
		{
			int messageLength = 0;

			if (messageStream != null)
				messageLength = (int)messageStream.Length;
			else
				messageLength = 0;

			bool useNetworkOrder = pool.Settings.UseNetworkOrder;

			byte[] length = BitConverter.GetBytes(GetNetworkOrdered(messageLength + envelopeSize, useNetworkOrder));
			byte[] commandIdBytes;
			byte[] messageIdBytes = null;
			//byte[] code = BitConverter.GetBytes(GetNetworkOrdered(commandId, useNetworkOrder));
			if (messageId != 0)
			{
				commandIdBytes = BitConverter.GetBytes(GetNetworkOrdered(commandId, useNetworkOrder));
				messageIdBytes = BitConverter.GetBytes(GetNetworkOrdered(messageId, useNetworkOrder));
			}
			else
			{
				commandIdBytes = BitConverter.GetBytes(GetNetworkOrdered((int)commandId, useNetworkOrder));
			}

			//MemoryStream rebufferedStream = new MemoryStream(envelopeSize + messageLength);			

			ResourcePoolItem<MemoryStream> rebufferedStreamItem = pool.GetPooledStream();

			MemoryStream rebufferedStream = rebufferedStreamItem.Item;

			rebufferedStream.Write(GetMessageStarter(useNetworkOrder), 0, 2);
			rebufferedStream.Write(length, 0, 4);
			//rebufferedStream.Write(code, 0, 4);
			if (messageId != 0)
			{
				if (useNetworkOrder)
				{
					rebufferedStream.Write(messageIdBytes, 0, 2);
					rebufferedStream.Write(commandIdBytes, 0, 2);
				}
				else
				{
					rebufferedStream.Write(commandIdBytes, 0, 2);
					rebufferedStream.Write(messageIdBytes, 0, 2);
				}
			}
			else //backwards compatible, just send the command as an int
			{
				rebufferedStream.Write(commandIdBytes, 0, 4);
			}

			if (isSync)
				rebufferedStream.Write(doSendReply, 0, doSendReply.Length);
			else
				rebufferedStream.Write(dontSendReply, 0, dontSendReply.Length);

			if (messageStream != null)
			{
				messageStream.WriteTo(rebufferedStream);
			}
			rebufferedStream.Write(GetMessageTerminator(useNetworkOrder), 0, 2);

			return rebufferedStreamItem;
		}
		internal ResourcePoolItem<MemoryStream> CreateSyncMessage(Int16 commandId, Int16 messageId, MemoryStream messageStream, SocketPool pool)
		{
			return CreateMessage(commandId, messageId, messageStream, true, pool);
		}
		internal ResourcePoolItem<MemoryStream> CreateOneWayMessage(int commandId, MemoryStream messageStream, SocketPool pool)
		{
			return CreateMessage((short)commandId, 0, messageStream, false, pool);
		}
 internal ArrayManagedSocket(SocketSettings settings, SocketPool pool, int index)
     : base(settings, pool)
 {
     this.Index = index;
 }
		private void SendOneWay(SocketPool pool, int commandID, MemoryStream messageStream)
		{
			ManagedSocket socket = null;
			ResourcePoolItem<MemoryStream> rebufferedStreamItem = CreateOneWayMessage(commandID, messageStream, pool);

			try
			{
				MemoryStream rebufferedStream = rebufferedStreamItem.Item;
				socket = pool.GetSocket();
				// GetBuffer() should be used in preference to ToArray() where possible
				// as it does not allocate a new byte[] like ToArray does().
				byte[] messageBuffer = rebufferedStream.GetBuffer();
				socket.Send(messageBuffer, (int)rebufferedStream.Length, SocketFlags.None);
			}
			catch (SocketException sex)
			{
				if (socket != null)
				{
					socket.LastError = sex.SocketErrorCode;
				}
				throw;
			}
			finally
			{
				if (socket != null)
				{
					socket.Release();
				}
				rebufferedStreamItem.Release();
			}
		}
		/// <summary>
		/// Called by XmlSerializationSectionHandler when the config is reloaded.
		/// </summary>
		public void ReloadConfig(object sender, EventArgs args)
		{
			SocketClientConfig newConfig = GetConfig();
			if (mySettings == defaultMessageSettings) //current using defaults, if defaults change we want to change the active socket pool
			{
				if (!newConfig.DefaultSocketSettings.SameAs(defaultMessageSettings)) //settings have changed, need to change "mySocketPool(s)" reference
				{
                    if (log.IsInfoEnabled)
                        log.Info("Default socket settings changed, updating default socket pool.");

					mySocketPools = SocketManager.Instance.GetSocketPools(newConfig.DefaultSocketSettings);
					if (mySocketPool != null && myEndPoint != null)
					{
						SocketPool oldDefault = mySocketPool;
						mySocketPool = GetSocketPool(myEndPoint, newConfig.DefaultSocketSettings);
						oldDefault.ReleaseAndDisposeAll();
					}
				}
				mySettings = newConfig.DefaultSocketSettings;
			}

			defaultMessageSettings = newConfig.DefaultSocketSettings;
			config = newConfig;
		}
Beispiel #26
0
 internal LinkedManagedSocket(SocketSettings settings, SocketPool pool)
     : base(settings, pool)
 {
 }
Beispiel #27
0
        /// <summary>
        /// Sends a message to a server that does not expect a reply.
        /// </summary>
        /// <param name="destination">The server's EndPoint</param>
        /// <param name="messageSettings">Settings for the transport.</param>
        /// <param name="commandID">The Command Identifier to send to the server. The server's IMessageHandler should know about all possible CommandIDs</param>
        /// <param name="messageStream">The contents of the message for the server to process.</param>
        public void SendOneWay(IPEndPoint destination, SocketSettings messageSettings, int commandID, MemoryStream messageStream)
        {
            SocketPool socketPool = GetSocketPool(destination, messageSettings);

            SendOneWay(socketPool, commandID, messageStream);
        }
Beispiel #28
0
 /// <summary>
 /// Create a new SocketClient with a default connection to destination, using the default settings.
 /// </summary>
 public SocketClient(IPEndPoint destination)
     : this()
 {
     myEndPoint   = destination;
     mySocketPool = GetSocketPool(destination);
 }
Beispiel #29
0
        private ResourcePoolItem <MemoryStream> CreateMessage(short commandId, short messageId, MemoryStream messageStream, bool isSync, SocketPool pool)
        {
            int messageLength = 0;

            if (messageStream != null)
            {
                messageLength = (int)messageStream.Length;
            }
            else
            {
                messageLength = 0;
            }

            bool useNetworkOrder = pool.Settings.UseNetworkOrder;

            byte[] length = BitConverter.GetBytes(GetNetworkOrdered(messageLength + envelopeSize, useNetworkOrder));
            byte[] commandIdBytes;
            byte[] messageIdBytes = null;
            //byte[] code = BitConverter.GetBytes(GetNetworkOrdered(commandId, useNetworkOrder));
            if (messageId != 0)
            {
                commandIdBytes = BitConverter.GetBytes(GetNetworkOrdered(commandId, useNetworkOrder));
                messageIdBytes = BitConverter.GetBytes(GetNetworkOrdered(messageId, useNetworkOrder));
            }
            else
            {
                commandIdBytes = BitConverter.GetBytes(GetNetworkOrdered((int)commandId, useNetworkOrder));
            }

            //MemoryStream rebufferedStream = new MemoryStream(envelopeSize + messageLength);

            ResourcePoolItem <MemoryStream> rebufferedStreamItem = pool.GetPooledStream();

            MemoryStream rebufferedStream = rebufferedStreamItem.Item;

            rebufferedStream.Write(GetMessageStarter(useNetworkOrder), 0, 2);
            rebufferedStream.Write(length, 0, 4);
            //rebufferedStream.Write(code, 0, 4);
            if (messageId != 0)
            {
                if (useNetworkOrder)
                {
                    rebufferedStream.Write(messageIdBytes, 0, 2);
                    rebufferedStream.Write(commandIdBytes, 0, 2);
                }
                else
                {
                    rebufferedStream.Write(commandIdBytes, 0, 2);
                    rebufferedStream.Write(messageIdBytes, 0, 2);
                }
            }
            else             //backwards compatible, just send the command as an int
            {
                rebufferedStream.Write(commandIdBytes, 0, 4);
            }

            if (isSync)
            {
                rebufferedStream.Write(doSendReply, 0, doSendReply.Length);
            }
            else
            {
                rebufferedStream.Write(dontSendReply, 0, dontSendReply.Length);
            }

            if (messageStream != null)
            {
                messageStream.WriteTo(rebufferedStream);
            }
            rebufferedStream.Write(GetMessageTerminator(useNetworkOrder), 0, 2);

            return(rebufferedStreamItem);
        }
Beispiel #30
0
 internal ResourcePoolItem <MemoryStream> CreateSyncMessage(Int16 commandId, Int16 messageId, MemoryStream messageStream, SocketPool pool)
 {
     return(CreateMessage(commandId, messageId, messageStream, true, pool));
 }
Beispiel #31
0
 /// <summary>
 /// Create a new SocketClient with a default connection to destination, using the supplied settings.
 /// </summary>
 public SocketClient(IPEndPoint destination, SocketSettings settings)
 {
     mySettings    = settings;
     mySocketPools = SocketManager.Instance.GetSocketPools(settings);
     mySocketPool  = SocketManager.Instance.GetSocketPool(destination, settings);
 }
Beispiel #32
0
 internal ResourcePoolItem <MemoryStream> CreateOneWayMessage(int commandId, MemoryStream messageStream, SocketPool pool)
 {
     return(CreateMessage((short)commandId, 0, messageStream, false, pool));
 }
		private MemoryStream SendSync(SocketPool pool, int commandID, MemoryStream messageStream)
		{
			short messageId = (short)1; //new async scheme doesn't currently need these.
			ResourcePoolItem<MemoryStream> rebufferedStreamItem = CreateSyncMessage((short)commandID, messageId, messageStream, pool);
			MemoryStream rebufferedStream = rebufferedStreamItem.Item;

			ManagedSocket socket = null;
			MemoryStream replyStream = null;

			try
			{
				socket = pool.GetSocket();

				// GetBuffer() should be used in preference to ToArray() where possible
				// as it does not allocate a new byte[] like ToArray does().
				socket.Send(rebufferedStream.GetBuffer(), (int)rebufferedStream.Length, SocketFlags.None);
				replyStream = socket.GetReply();
			}
			catch (ThreadAbortException)
			{
				if (socket != null)
				{
					socket.LastError = SocketError.TimedOut;
				}
				log.Warn("Thread aborted on SocketClient.");
				throw;
			}
			catch (SocketException ex)
			{
				if (socket != null)
				{
					socket.LastError = ex.SocketErrorCode;
				}
				throw;
			}
			finally
			{
				rebufferedStreamItem.Release();
				if (socket != null) //getting the socket can throw a timedout exception due to limiting, in which case the socket will be null
				{
					socket.Release();
				}
			}

			return replyStream;
		}