コード例 #1
0
        /// <summary>
        ///	<para>Sends the data in <paramref name="sendData"/> to <see cref="EndPoint"/>.
        ///	Calls <paramref name="resultAction"/> when response data has been recieved,
        ///	the operation times-out, or the operation fails.</para>
        /// </summary>
        /// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param>
        /// <param name="sendData">
        ///	<para>The data to send. The pool item will be disposed, returned to the owning pool,
        ///	automatically when it is no longer needed. So it is important that consumers do not
        ///	access it after calling this method.</para>
        /// </param>
        /// <param name="resultAction">
        ///	<para>The method that will be called when the end point responds,
        ///	the operation fails, or the operation times out.</para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///	<para><paramref name="sendData"/> is <see langword="null"/>.</para>
        /// </exception>
        public void SendRoundTripAsync(
            int timeout,
            IPoolItem <MemoryStream> sendData,
            Action <RoundTripAsyncEventArgs> resultAction)
        {
            if (sendData == null)
            {
                throw new ArgumentNullException("sendData");
            }

            var task = new AsyncSocketTask(this);

            task.SetEnumerator(GetSendEnumerator(
                                   timeout,
                                   sendData,
                                   OperationType.RoundTrip,
                                   resultAction,
                                   task.Callback));

            task.Execute(true);
        }
コード例 #2
0
ファイル: SocketChannel.cs プロジェクト: wilson0x4d/DataRelay
        /// <summary>
        ///	<para>Sends the data in <paramref name="sendData"/> to the remote end point
        ///	specified during construction. Calls <paramref name="resultAction"/> when all data
        ///	has been sent. Please note that this only indicates that the server received the data
        ///	and does not guarantee that data was processed.</para>
        /// </summary>
        /// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param>
        /// <param name="sendData">
        ///	<para>The data to send. The pool item will be disposed, returned to the owning pool,
        ///	automatically when it is no longer needed. So it is important that consumers do not
        ///	access it after calling this method.</para>
        /// </param>
        /// <param name="resultAction">
        ///	<para>The method that will be called when the host acknowledges that the data was
        ///	received, the operation fails, or the operation times out.</para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///	<para><paramref name="sendData"/> is <see langword="null"/>.</para>
        /// </exception>
        public void SendOneWayAsync(
            int timeout,
            IPoolItem <MemoryStream> sendData,
            Action <OneWayAsyncEventArgs> resultAction)
        {
            if (sendData == null)
            {
                throw new ArgumentNullException("sendData");
            }

            _currentRequestId = Interlocked.Increment(ref _nextRequestId);

            var task = new AsyncSocketTask(this);

            task.SetEnumerator(GetSendEnumerator(
                                   timeout,
                                   sendData,
                                   OperationType.OneWay,
                                   resultAction,
                                   task.Callback));

            task.Execute(true);
        }
コード例 #3
0
        private IEnumerator <bool> GetSendEnumerator(
            int timeout,
            IPoolItem <MemoryStream> sendData,
            OperationType type,
            Delegate resultAction,
            ParameterlessDelegate callback)
        {
            ValidateSocketForUse();

            _sendData      = sendData;
            _operationType = type;
            if (_operationType == OperationType.OneWay)
            {
                _oneWayResultAction = (Action <OneWayAsyncEventArgs>)resultAction;
            }
            else if (_operationType == OperationType.RoundTrip)
            {
                _roundTripResultAction = (Action <RoundTripAsyncEventArgs>)resultAction;
                _responseData          = AsyncSocketClient.MemoryPool.Borrow();
            }
            else
            {
                string message = string.Format("Unexpected operation type '{0}'", type);
                Debug.Fail(message);
                SetError(new InvalidOperationException(message));
                yield break;
            }

            _socketArgs.UserToken = callback;

            if (_state == State.Uninitialized)
            {
                _state = State.Connecting;
                var connectTimeoutHandle = TaskMonitor.RegisterMonitor(_connectTimeout, _timeoutHandler, null);
                if (_socket.ConnectAsync(_socketArgs))
                {
                    yield return(false);
                }
                if (!connectTimeoutHandle.TrySetComplete())
                {
                    SetError(SocketError.TimedOut);
                    yield break;
                }
                if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Connect))
                {
                    yield break;
                }

                _state = State.Connected;

                ThreadPool.UnsafeQueueUserWorkItem(o =>
                {
                    var target = (SocketChannel)o;
                    var task   = new AsyncSocketTask(this);
                    task.SetEnumerator(target.GetReceiveEnumerator(task.Callback));
                    task.Execute(false);
                }, this);
            }

            Debug.Assert(_sendData != null, "_sendData was not set prior to starting the send enumerator.");
            _socketArgs.SetBuffer(_sendData.Item.GetBuffer(), (int)_sendData.Item.Position, (int)_sendData.Item.Length);
            _timeoutHandle = TaskMonitor.RegisterMonitor(timeout, _timeoutHandler, null);
            if (_socket.SendAsync(_socketArgs))
            {
                yield return(false);
            }
            if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Send))
            {
                yield break;
            }

            _messageSent = true;
        }
コード例 #4
0
		private IEnumerator<bool> GetSendEnumerator(
			int timeout,
			IPoolItem<MemoryStream> sendData,
			OperationType type,
			Delegate resultAction,
			ParameterlessDelegate callback)
		{
			ValidateSocketForUse();

			_sendData = sendData;
			_operationType = type;
			if (_operationType == OperationType.OneWay)
			{
				_oneWayResultAction = (Action<OneWayAsyncEventArgs>)resultAction;
			}
			else if (_operationType == OperationType.RoundTrip)
			{
				_roundTripResultAction = (Action<RoundTripAsyncEventArgs>)resultAction;
				_responseData = AsyncSocketClient.MemoryPool.Borrow();
			}
			else
			{
				string message = string.Format("Unexpected operation type '{0}'", type);
				Debug.Fail(message);
				SetError(new InvalidOperationException(message));
				yield break;
			}

			_socketArgs.UserToken = callback;

			if (_state == State.Uninitialized)
			{
				_state = State.Connecting;
				var connectTimeoutHandle = TaskMonitor.RegisterMonitor(_connectTimeout, _timeoutHandler, null);
				if (_socket.ConnectAsync(_socketArgs)) yield return false;
				if (!connectTimeoutHandle.TrySetComplete())
				{
					SetError(SocketError.TimedOut);
					yield break;
				}
				if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Connect)) yield break;

				_state = State.Connected;

				ThreadPool.UnsafeQueueUserWorkItem(o =>
				{
					var target = (SocketChannel)o;
					var task = new AsyncSocketTask(this);
					task.SetEnumerator(target.GetReceiveEnumerator(task.Callback));
					task.Execute(false);
				}, this);
			}

			Debug.Assert(_sendData != null, "_sendData was not set prior to starting the send enumerator.");
			_socketArgs.SetBuffer(_sendData.Item.GetBuffer(), (int)_sendData.Item.Position, (int)_sendData.Item.Length);
			_timeoutHandle = TaskMonitor.RegisterMonitor(timeout, _timeoutHandler, null);
			if (_socket.SendAsync(_socketArgs)) yield return false;
			if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Send)) yield break;

			_messageSent = true;
		}
コード例 #5
0
		/// <summary>
		///	<para>Sends the data in <paramref name="sendData"/> to <see cref="EndPoint"/>.
		///	Calls <paramref name="resultAction"/> when response data has been recieved,
		///	the operation times-out, or the operation fails.</para>
		/// </summary>
		/// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param>
		/// <param name="sendData">
		///	<para>The data to send. The pool item will be disposed, returned to the owning pool,
		///	automatically when it is no longer needed. So it is important that consumers do not
		///	access it after calling this method.</para>
		/// </param>
		/// <param name="resultAction">
		///	<para>The method that will be called when the end point responds,
		///	the operation fails, or the operation times out.</para>
		/// </param>
		/// <exception cref="ArgumentNullException">
		///	<para><paramref name="sendData"/> is <see langword="null"/>.</para>
		/// </exception>
		public void SendRoundTripAsync(
			int timeout,
			IPoolItem<MemoryStream> sendData,
			Action<RoundTripAsyncEventArgs> resultAction)
		{
			if (sendData == null) throw new ArgumentNullException("sendData");

			var task = new AsyncSocketTask(this);

			task.SetEnumerator(GetSendEnumerator(
				timeout,
				sendData,
				OperationType.RoundTrip,
				resultAction,
				task.Callback));

			task.Execute(true);
		}
コード例 #6
0
ファイル: SocketChannel.cs プロジェクト: wilson0x4d/DataRelay
        private IEnumerator <bool> GetSendEnumerator(
            int timeout,
            IPoolItem <MemoryStream> sendData,
            OperationType type,
            Delegate resultAction,
            ParameterlessDelegate callback)
        {
            ValidateSocketForUse();

            _sendData      = sendData;
            _operationType = type;
            if (_operationType == OperationType.OneWay)
            {
                _oneWayResultAction = (Action <OneWayAsyncEventArgs>)resultAction;
            }
            else if (_operationType == OperationType.RoundTrip)
            {
                _roundTripResultAction = (Action <RoundTripAsyncEventArgs>)resultAction;
                _responseData          = AsyncSocketClient.MemoryPool.Borrow();
            }
            else
            {
                string message = string.Format("Unexpected operation type '{0}'", type);
                Debug.Fail(message);
                SetError(new InvalidOperationException(message));
                yield break;
            }

            _socketArgs.UserToken = callback;

            if (_state == State.Uninitialized)
            {
                LogDebugStep("Connecting...");
                _state = State.Connecting;
                var connectTimeoutHandle = TaskMonitor.RegisterMonitor(_connectTimeout, _timeoutHandler, null);
                if (_socket.ConnectAsync(_socketArgs))
                {
                    yield return(false);
                }
                if (!connectTimeoutHandle.TrySetComplete())
                {
                    LogDebugStep("Failed to set connection timeout handle complete.");
                    SetError(SocketError.TimedOut);
                    yield break;
                }
                if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Connect))
                {
                    yield break;
                }

                _state = State.Connected;
                LogDebugStep("Connected.");

                ThreadPool.UnsafeQueueUserWorkItem(o =>
                {
                    var target = (SocketChannel)o;
                    var task   = new AsyncSocketTask(this);
                    task.SetEnumerator(target.GetReceiveEnumerator(task.Callback));
                    task.Execute(false);
                }, this);
            }

            Debug.Assert(_sendData != null, "_sendData was not set prior to starting the send enumerator.");
            _socketArgs.SetBuffer(_sendData.Item.GetBuffer(), (int)_sendData.Item.Position, (int)_sendData.Item.Length);
            _timeoutHandle = TaskMonitor.RegisterMonitor(timeout, _timeoutHandler, null);
            // note - it seems this is necessary because of a bug in the SendAsync function
            // see - http://social.msdn.microsoft.com/Forums/en-IE/ncl/thread/40fe397c-b1da-428e-a355-ee5a6b0b4d2c
            Thread.MemoryBarrier();
            if (_log.IsDebugEnabled)
            {
                LogDebugStep(string.Format("Sending {0:###,###,###,##0} bytes", _sendData.Item.Length - _sendData.Item.Position));
            }
            if (_socket.SendAsync(_socketArgs))
            {
                yield return(false);
            }
            if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Send))
            {
                yield break;
            }

            _messageSent = true;
        }