Beispiel #1
0
        //
        // Async Winsock Support, the following functions use either
        //   the Async Winsock support to do overlapped I/O WSASend/WSARecv
        //   or a WSAEventSelect call to enable selection and non-blocking mode
        //   of otherwise normal Winsock calls.
        //
        //   Currently the following Async Socket calls are supported:
        //      Send, Recv, SendTo, RecvFrom, Connect, Accept
        //

        /*++

        Routine Description:

           BeginConnect - Does a async winsock connect, by calling
           WSAEventSelect to enable Connect Events to signal an event and
           wake up a callback which involkes a callback.

            So note: This routine may go pending at which time,
            but any case the callback Delegate will be called upon completion

        Arguments:

           remoteEP - status line that we wish to parse
           Callback - Async Callback Delegate that is called upon Async Completion
           State - State used to track callback, set by caller, not required

        Return Value:

           IAsyncResult - Async result used to retreive result

        --*/

        /// <include file='doc\Socket.uex' path='docs/doc[@for="Socket.BeginConnect"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public IAsyncResult BeginConnect(EndPoint remoteEP, AsyncCallback callback, Object state) {
            if (CleanedUp) {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            //
            // parameter validation
            //
            if (remoteEP==null) {
                throw new ArgumentNullException("remoteEP");
            }

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginConnect() remoteEP:" + remoteEP.ToString());

            //
            // ask the EndPoint to generate a SocketAddress that we
            // can pass down to winsock
            //
            EndPoint endPointSnapshot = remoteEP;
            if (remoteEP.GetType()==typeof(IPEndPoint)) {
                endPointSnapshot = new IPEndPoint(((IPEndPoint)remoteEP).Address, ((IPEndPoint)remoteEP).Port);
            }
            SocketAddress socketAddress = endPointSnapshot.Serialize();

            // This will check the permissions for connect.
            CheckCacheRemote(socketAddress, endPointSnapshot, true);

            // get async going
            SetAsyncEventSelect(AsyncEventBits.FdConnect);

            ConnectAsyncResult asyncResult = new ConnectAsyncResult(this, state, callback);

            int errorCode =
                UnsafeNclNativeMethods.OSSOCK.connect(
                    m_Handle,
                    socketAddress.m_Buffer,
                    socketAddress.m_Size );

            if (errorCode!=SocketErrors.Success) {
                errorCode = Marshal.GetLastWin32Error();
            }

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginConnect() UnsafeNclNativeMethods.OSSOCK.connect returns:" + errorCode.ToString());

            if (errorCode==SocketErrors.Success) {
                SetToConnected();
            }
            asyncResult.CheckAsyncCallResult(errorCode);

            //
            // if the asynchronous native call fails synchronously
            // we'll throw a SocketException
            //
            if (asyncResult.ErrorCode!=SocketErrors.Success) {
                //
                // update our internal state after this socket error and throw
                //
                UpdateStatusAfterSocketError();
                throw new SocketException(asyncResult.ErrorCode);
            }

            if (m_RightEndPoint==null) {
                //
                // save a copy of the EndPoint so we can use it for Create()
                //
                m_RightEndPoint = endPointSnapshot;
            }

            GlobalLog.Print( "BeginConnect() to:" + endPointSnapshot.ToString() + " returning AsyncResult:" + ValidationHelper.HashString(asyncResult));

            return asyncResult;
        }