Beispiel #1
0
        internal void SetUnmanagedStructures(IList <ArraySegment <byte> > buffers)
        {
            // Fill in Buffer Array structure that will be used for our send/recv Buffer.
            // Make sure we don't let the app mess up the buffer array enough to cause
            // corruption.
            int count = buffers.Count;

            ArraySegment <byte>[] buffersCopy = new ArraySegment <byte> [count];

            for (int i = 0; i < count; i++)
            {
                buffersCopy[i] = buffers[i];
                RangeValidationHelpers.ValidateSegment(buffersCopy[i]);
            }

            _wsaBuffers = new WSABuffer[count];

            object[] objectsToPin = new object[count];
            for (int i = 0; i < count; i++)
            {
                objectsToPin[i] = buffersCopy[i].Array;
            }

            base.SetUnmanagedStructures(objectsToPin);

            for (int i = 0; i < count; i++)
            {
                _wsaBuffers[i].Length  = buffersCopy[i].Count;
                _wsaBuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffersCopy[i].Array, buffersCopy[i].Offset);
            }
        }
Beispiel #2
0
        // Joins a multicast address group with the specified time to live (TTL).
        public void JoinMulticastGroup(IPAddress multicastAddr, int timeToLive)
        {
            // parameter validation;
            if (_cleanedUp)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (multicastAddr == null)
            {
                throw new ArgumentNullException(nameof(multicastAddr));
            }
            if (!RangeValidationHelpers.ValidateRange(timeToLive, 0, 255))
            {
                throw new ArgumentOutOfRangeException(nameof(timeToLive));
            }

            // Join the Multicast Group.
            JoinMulticastGroup(multicastAddr);

            // Set Time To Live (TTL).
            _clientSocket.SetSocketOption(
                (_family == AddressFamily.InterNetwork) ? SocketOptionLevel.IP : SocketOptionLevel.IPv6,
                SocketOptionName.MulticastTimeToLive,
                timeToLive);
        }
Beispiel #3
0
        public static SocketError Receive(SafeCloseSocket handle, IList <ArraySegment <byte> > buffers, ref SocketFlags socketFlags, out int bytesTransferred)
        {
            int count = buffers.Count;

            WSABuffer[] WSABuffers   = new WSABuffer[count];
            GCHandle[]  objectsToPin = null;

            try
            {
                objectsToPin = new GCHandle[count];
                for (int i = 0; i < count; ++i)
                {
                    ArraySegment <byte> buffer = buffers[i];
                    RangeValidationHelpers.ValidateSegment(buffer);
                    objectsToPin[i]       = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
                    WSABuffers[i].Length  = buffer.Count;
                    WSABuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset);
                }

                // This can throw ObjectDisposedException.
                unsafe
                {
                    SocketError errorCode = Interop.Winsock.WSARecv(
                        handle.DangerousGetHandle(),
                        WSABuffers,
                        count,
                        out bytesTransferred,
                        ref socketFlags,
                        null,
                        IntPtr.Zero);

                    if (errorCode == SocketError.SocketError)
                    {
                        errorCode = GetLastSocketError();
                    }

                    return(errorCode);
                }
            }
            finally
            {
                if (objectsToPin != null)
                {
                    for (int i = 0; i < objectsToPin.Length; ++i)
                    {
                        if (objectsToPin[i].IsAllocated)
                        {
                            objectsToPin[i].Free();
                        }
                    }
                }
            }
        }
Beispiel #4
0
        // Joins a multicast address group with the specified time to live (TTL).
        public void JoinMulticastGroup(IPAddress multicastAddr, int timeToLive)
        {
            ThrowIfDisposed();

            ArgumentNullException.ThrowIfNull(multicastAddr);
            if (!RangeValidationHelpers.ValidateRange(timeToLive, 0, 255))
            {
                throw new ArgumentOutOfRangeException(nameof(timeToLive));
            }

            // Join the Multicast Group.
            JoinMulticastGroup(multicastAddr);

            // Set Time To Live (TTL).
            _clientSocket.SetSocketOption(
                (_family == AddressFamily.InterNetwork) ? SocketOptionLevel.IP : SocketOptionLevel.IPv6,
                SocketOptionName.MulticastTimeToLive,
                timeToLive);
        }
Beispiel #5
0
        public static SocketError Receive(SafeSocketHandle handle, IList <ArraySegment <byte> > buffers, SocketFlags socketFlags, out int bytesTransferred)
        {
            const int StackThreshold = 16; // arbitrary limit to avoid too much space on stack (note: may be over-sized, that's OK - length passed separately)
            int       count          = buffers.Count;
            bool      useStack       = count <= StackThreshold;

            WSABuffer[]? leasedWSA = null;
            GCHandle[]? leasedGC   = null;
            Span <WSABuffer> WSABuffers   = stackalloc WSABuffer[0];
            Span <GCHandle>  objectsToPin = stackalloc GCHandle[0];

            if (useStack)
            {
                WSABuffers   = stackalloc WSABuffer[StackThreshold];
                objectsToPin = stackalloc GCHandle[StackThreshold];
            }
            else
            {
                WSABuffers = leasedWSA = ArrayPool <WSABuffer> .Shared.Rent(count);

                objectsToPin = leasedGC = ArrayPool <GCHandle> .Shared.Rent(count);
            }
            objectsToPin = objectsToPin.Slice(0, count);
            objectsToPin.Clear(); // note: touched in finally

            try
            {
                for (int i = 0; i < count; ++i)
                {
                    ArraySegment <byte> buffer = buffers[i];
                    RangeValidationHelpers.ValidateSegment(buffer);
                    objectsToPin[i]       = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
                    WSABuffers[i].Length  = buffer.Count;
                    WSABuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array !, buffer.Offset);
                }

                unsafe
                {
                    SocketError errorCode = Interop.Winsock.WSARecv(
                        handle,
                        WSABuffers,
                        count,
                        out bytesTransferred,
                        ref socketFlags,
                        null,
                        IntPtr.Zero);

                    if (errorCode == SocketError.SocketError)
                    {
                        errorCode = GetLastSocketError();
                    }

                    return(errorCode);
                }
            }
            finally
            {
                for (int i = 0; i < count; ++i)
                {
                    if (objectsToPin[i].IsAllocated)
                    {
                        objectsToPin[i].Free();
                    }
                }
                if (!useStack)
                {
                    ArrayPool <WSABuffer> .Shared.Return(leasedWSA !);

                    ArrayPool <GCHandle> .Shared.Return(leasedGC !);
                }
            }
        }