// // This is the static internal callback that will be called when // the IO we issued for the user to winsock has completed, either // synchronously (Signaled=false) or asynchronously (Signaled=true) // when this function gets called it must: // 1) update the AsyncResult object with the results of the completed IO // 2) signal events that the user might be waiting on // 3) cal the callback function that the user might have specified // internal static void ConnectCallback(object stateObject, bool Signaled) { ConnectAsyncResult asyncResult = stateObject as ConnectAsyncResult; Socket socket = asyncResult.AsyncObject as Socket; GlobalLog.Enter("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", "Signaled:" + Signaled.ToString()); GlobalLog.Assert(!asyncResult.IsCompleted, "Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() asyncResult.IsCompleted", ""); // // we now need to get the status of the async completion, we had an easy implementation // that uses GetSocketOption(), but VadimE suggested not to use this 'cause it may be // buggy on some platforms, so we use WSAEnumNetworkEvents() instead: // // The best way to do this is to call WSAEnumNetworkEvents and use the error code iError // array corresponding to FD_CONNECT. getsockopt (SO_ERROR) may return NO_ERROR under // stress even in case of error at least on Winnt4.0 (I don't remember whether I fixed // it on Win2000 or WinXP). // // // get async completion // /* * int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); * GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString()); */ NetworkEvents networkEvents = new NetworkEvents(); networkEvents.Events = AsyncEventBits.FdConnect; AutoResetEvent chkAsyncEvent = socket.m_AsyncEvent; int errorCode = SocketErrors.WSAENOTSOCK; if (chkAsyncEvent != null) { errorCode = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents( socket.m_Handle, chkAsyncEvent.Handle, ref networkEvents); if (errorCode != SocketErrors.Success) { errorCode = Marshal.GetLastWin32Error(); GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString()); } else { errorCode = networkEvents.ErrorCodes[(int)AsyncEventBitsPos.FdConnectBit]; GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString()); } } try { // // cancel async event // socket.SetAsyncEventSelect(AsyncEventBits.FdNone); // // go back to blocking mode // socket.InternalSetBlocking(true); } catch (Exception exception) { GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() caught exception::" + exception.Message); asyncResult.Result = exception; } // // if the native non-blocking call failed we'll throw a SocketException in EndConnect() // if (errorCode != SocketErrors.Success) { // // just save the error code, the SocketException will be thrown in EndConnect() // asyncResult.ErrorCode = errorCode; } else { // // the Socket is connected, update our state and performance counter // socket.SetToConnected(); } // // call the user's callback now, if there is one. // asyncResult.InvokeCallback(false); GlobalLog.Leave("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", errorCode.ToString()); }
internal IAsyncResult UnsafeBeginConnect(IPEndPoint remoteEP, AsyncCallback callback, object state) { if (CanUseConnectEx(remoteEP)) { return BeginConnectEx(remoteEP, false, callback, state); } EndPoint endPointSnapshot = remoteEP; var asyncResult = new ConnectAsyncResult(this, endPointSnapshot, state, callback); // For connectionless protocols, Connect is not an I/O call. Connect(remoteEP); asyncResult.FinishPostingAsyncOp(); // Synchronously complete the I/O and call the user's callback. asyncResult.InvokeCallback(); return asyncResult; }
// // This is the static internal callback that will be called when // the IO we issued for the user to winsock has completed, either // synchronously (Signaled=false) or asynchronously (Signaled=true) // when this function gets called it must: // 1) update the AsyncResult object with the results of the completed IO // 2) signal events that the user might be waiting on // 3) cal the callback function that the user might have specified // internal static void ConnectCallback(object stateObject, bool Signaled) { ConnectAsyncResult asyncResult = stateObject as ConnectAsyncResult; Socket socket = asyncResult.AsyncObject as Socket; GlobalLog.Enter("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", "Signaled:" + Signaled.ToString()); GlobalLog.Assert(!asyncResult.IsCompleted, "Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() asyncResult.IsCompleted", ""); // // // get async completion // /* * int errorCode = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); * GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() GetSocketOption() returns errorCode:" + errorCode.ToString()); */ NetworkEvents networkEvents = new NetworkEvents(); networkEvents.Events = AsyncEventBits.FdConnect; AutoResetEvent chkAsyncEvent = socket.m_AsyncEvent; int errorCode = SocketErrors.WSAENOTSOCK; if (chkAsyncEvent != null) { errorCode = UnsafeNclNativeMethods.OSSOCK.WSAEnumNetworkEvents( socket.m_Handle, chkAsyncEvent.Handle, ref networkEvents); if (errorCode != SocketErrors.Success) { errorCode = Marshal.GetLastWin32Error(); GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() WSAEnumNetworkEvents() failed with errorCode:" + errorCode.ToString()); } else { errorCode = networkEvents.ErrorCodes[(int)AsyncEventBitsPos.FdConnectBit]; GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() ErrorCodes(FdConnect) got errorCode:" + errorCode.ToString()); } } try { // // cancel async event // socket.SetAsyncEventSelect(AsyncEventBits.FdNone); // // go back to blocking mode // socket.InternalSetBlocking(true); } catch (Exception exception) { GlobalLog.Print("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback() caught exception::" + exception.Message); asyncResult.Result = exception; } // // if the native non-blocking call failed we'll throw a SocketException in EndConnect() // if (errorCode != SocketErrors.Success) { // // just save the error code, the SocketException will be thrown in EndConnect() // asyncResult.ErrorCode = errorCode; } else { // // the Socket is connected, update our state and performance counter // socket.SetToConnected(); } // // call the user's callback now, if there is one. // asyncResult.InvokeCallback(false); GlobalLog.Leave("Socket#" + ValidationHelper.HashString(socket) + "::ConnectCallback", errorCode.ToString()); }