_ReceiveMessageOverlappedAsyncResult.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / Sockets / _ReceiveMessageOverlappedAsyncResult.cs / 1 / _ReceiveMessageOverlappedAsyncResult.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Net.Sockets { 
    using System; 
    using System.Net;
    using System.Runtime.InteropServices; 
    using System.Threading;
    using Microsoft.Win32;
    using System.Collections.Generic;
 
    //
    //  OverlappedAsyncResult - used to take care of storage for async Socket operation 
    //   from the BeginSend, BeginSendTo, BeginReceive, BeginReceiveFrom calls. 
    //
    unsafe internal class ReceiveMessageOverlappedAsyncResult: BaseOverlappedAsyncResult { 

        //
        // internal class members
        // 
        private UnsafeNclNativeMethods.OSSOCK.WSAMsg* m_Message;
        internal SocketAddress  SocketAddressOriginal; 
        internal SocketAddress  m_SocketAddress; 
        private WSABuffer*     m_WSABuffer;
        private byte[]         m_WSABufferArray; 
        private byte[]         m_ControlBuffer;
        internal byte[]        m_MessageBuffer;
        internal SocketFlags   m_flags;
 
        private static readonly int s_ControlDataSize =  Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.ControlData));
        private static readonly int s_ControlDataIPv6Size =  Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.ControlDataIPv6)); 
        private static readonly int s_WSABufferSize=Marshal.SizeOf(typeof(WSABuffer)); 
        private static readonly int s_WSAMsgSize = Marshal.SizeOf(typeof(UnsafeNclNativeMethods.OSSOCK.WSAMsg));
 
        internal IPPacketInformation m_IPPacketInformation;

        //
        // the following two will be used only on WinNT to enable completion ports 
        //
        // 
        // Constructor. We take in the socket that's creating us, the caller's 
        // state object, and the buffer on which the I/O will be performed.
        // We save the socket and state, pin the callers's buffer, and allocate 
        // an event for the WaitHandle.
        //
        internal ReceiveMessageOverlappedAsyncResult(Socket socket, Object asyncState, AsyncCallback asyncCallback) :
            base(socket, asyncState, asyncCallback) 
        { }
 
        internal IntPtr GetSocketAddressSizePtr() 
        {
            return Marshal.UnsafeAddrOfPinnedArrayElement(m_SocketAddress.m_Buffer, m_SocketAddress.GetAddressSizeOffset()); 
        }

        internal SocketAddress SocketAddress {
            get { 
                return m_SocketAddress;
            } 
        } 

 
        //
        // SetUnmanagedStructures -
        // Fills in Overlapped Structures used in an Async Overlapped Winsock call
        //   these calls are outside the runtime and are unmanaged code, so we need 
        //   to prepare specific structures and ints that lie in unmanaged memory
        //   since the Overlapped calls can be Async 
        // 

        internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, SocketAddress socketAddress, SocketFlags socketFlags) 
        {
            //ipv4 or ipv6?
            bool ipv4 = ((Socket)(AsyncObject)).AddressFamily == AddressFamily.InterNetwork;
            bool ipv6 = ((Socket)(AsyncObject)).AddressFamily == AddressFamily.InterNetworkV6; 

            m_MessageBuffer = new byte[s_WSAMsgSize]; 
            m_WSABufferArray = new byte[s_WSABufferSize]; 

            //prepare control buffer 
            if (ipv4) {
                m_ControlBuffer = new byte[s_ControlDataSize];
            }
            else if (ipv6) { 
                m_ControlBuffer = new byte[s_ControlDataIPv6Size];
            } 
 
            //pin buffers
            object[] objectsToPin = new object[(m_ControlBuffer != null)?5:4]; 
            objectsToPin[0] = buffer;
            objectsToPin[1] = m_MessageBuffer;
            objectsToPin[2] = m_WSABufferArray;
 
            //prepare socketaddress buffer
            m_SocketAddress = socketAddress; 
            m_SocketAddress.CopyAddressSizeIntoBuffer(); 
            objectsToPin[3] = m_SocketAddress.m_Buffer;
 
            if(m_ControlBuffer != null){
                objectsToPin[4] = m_ControlBuffer;
            }
 
            base.SetUnmanagedStructures(objectsToPin);
 
            //prepare data buffer 
            m_WSABuffer = (WSABuffer*) Marshal.UnsafeAddrOfPinnedArrayElement(m_WSABufferArray, 0);
            m_WSABuffer->Length = size; 
            m_WSABuffer->Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset);


            //setup structure 
            m_Message = (UnsafeNclNativeMethods.OSSOCK.WSAMsg*) Marshal.UnsafeAddrOfPinnedArrayElement(m_MessageBuffer, 0);
            m_Message->socketAddress = Marshal.UnsafeAddrOfPinnedArrayElement(m_SocketAddress.m_Buffer,0); 
            m_Message->addressLength = (uint)m_SocketAddress.Size; 
            m_Message->buffers = Marshal.UnsafeAddrOfPinnedArrayElement(m_WSABufferArray,0);
            m_Message->count = 1; 

            if(m_ControlBuffer != null){
                m_Message->controlBuffer.Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(m_ControlBuffer, 0);
                m_Message->controlBuffer.Length = m_ControlBuffer.Length; 
            }
 
            m_Message->flags = socketFlags; 
        }
 
        internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, SocketAddress socketAddress, SocketFlags socketFlags, ref OverlappedCache overlappedCache)
        {
            SetupCache(ref overlappedCache);
            SetUnmanagedStructures(buffer, offset, size, socketAddress, socketFlags); 
        }
 
        unsafe private void InitIPPacketInformation(){ 

            IPAddress address = null; 

            //ipv4
            if (m_ControlBuffer.Length == s_ControlDataSize) {
                UnsafeNclNativeMethods.OSSOCK.ControlData controlData = (UnsafeNclNativeMethods.OSSOCK.ControlData)Marshal.PtrToStructure(m_Message->controlBuffer.Pointer, typeof(UnsafeNclNativeMethods.OSSOCK.ControlData)); 
                if(controlData.length != UIntPtr.Zero)
                { 
                    address = new IPAddress((long)controlData.address); 
                }
                m_IPPacketInformation = new IPPacketInformation(((address!=null)?address:IPAddress.None),(int)controlData.index); 
            }
            //ipv6
            else if (m_ControlBuffer.Length == s_ControlDataIPv6Size){
                UnsafeNclNativeMethods.OSSOCK.ControlDataIPv6 controlData = (UnsafeNclNativeMethods.OSSOCK.ControlDataIPv6)Marshal.PtrToStructure(m_Message->controlBuffer.Pointer, typeof(UnsafeNclNativeMethods.OSSOCK.ControlDataIPv6)); 
                if (controlData.length != UIntPtr.Zero)
                { 
                    address = new IPAddress(controlData.address); 
                }
                m_IPPacketInformation = new IPPacketInformation(((address!=null)?address:IPAddress.IPv6None),(int)controlData.index); 
            }
            //other
            else{
                m_IPPacketInformation = new IPPacketInformation(); 
            }
        } 
 

        // 
        // This method is called after an asynchronous call is made for the user,
        // it checks and acts accordingly if the IO:
        // 1) completed synchronously.
        // 2) was pended. 
        // 3) failed.
        // 
 
        internal void SyncReleaseUnmanagedStructures()
        { 
            InitIPPacketInformation();
            ForceReleaseUnmanagedStructures();
        }
 

        protected override void ForceReleaseUnmanagedStructures() { 
            m_flags = m_Message->flags; 
            base.ForceReleaseUnmanagedStructures();
        } 

        internal override object PostCompletion(int numBytes)
        {
            InitIPPacketInformation(); 
            if (ErrorCode == 0) {
                if(Logging.On)LogBuffer(numBytes); 
            } 
            return (int)numBytes;
        } 

        void LogBuffer(int size) {
            GlobalLog.Assert(Logging.On, "ReceiveMessageOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", ValidationHelper.HashString(this));
            Logging.Dump(Logging.Sockets, AsyncObject, "PostCompletion", m_WSABuffer->Pointer, Math.Min(m_WSABuffer->Length, size)); 
        }
 
    }; // class OverlappedAsyncResult 

 


} // namespace System.Net.Sockets


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK