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(); } } } } }
} // OverlappedCallback() // // 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, SocketFlags socketFlags, EndPoint remoteEP, bool pinRemoteEP) { // // create the event handle // m_OverlappedEvent = new AutoResetEvent(false); // // fill in the overlapped structure with the event handle. // Marshal.WriteIntPtr( m_UnmanagedBlob, Win32.OverlappedhEventOffset, m_OverlappedEvent.Handle); // // Fill in Buffer Array structure that will be used for our send/recv Buffer // m_WSABuffer = new WSABuffer(); m_GCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); m_WSABuffer.Length = size; m_WSABuffer.Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); // // fill in flags if we use it. // m_Flags = socketFlags; // // if needed fill end point // if (remoteEP != null) { m_SocketAddress = remoteEP.Serialize(); if (pinRemoteEP) { m_GCHandleSocketAddress = GCHandle.Alloc(m_SocketAddress.m_Buffer, GCHandleType.Pinned); m_GCHandleSocketAddressSize = GCHandle.Alloc(m_SocketAddress.m_Size, GCHandleType.Pinned); } } } // SetUnmanagedStructures()
public static SocketError Send(SafeCloseSocket handle, BufferOffsetSize[] buffers, SocketFlags socketFlags, out int bytesTransferred) { WSABuffer[] WSABuffers = new WSABuffer[buffers.Length]; GCHandle[] objectsToPin = null; try { objectsToPin = new GCHandle[buffers.Length]; for (int i = 0; i < buffers.Length; ++i) { objectsToPin[i] = GCHandle.Alloc(buffers[i].Buffer, GCHandleType.Pinned); WSABuffers[i].Length = buffers[i].Size; WSABuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffers[i].Buffer, buffers[i].Offset); } // This can throw ObjectDisposedException. SocketError errorCode = Interop.Winsock.WSASend_Blocking( handle.DangerousGetHandle(), WSABuffers, WSABuffers.Length, out bytesTransferred, socketFlags, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } return(errorCode); } finally { if (objectsToPin != null) { for (int i = 0; i < objectsToPin.Length; ++i) { if (objectsToPin[i].IsAllocated) { objectsToPin[i].Free(); } } } } }
} // OverlappedCallback() // // 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, SocketFlags socketFlags, EndPoint remoteEP, bool pinRemoteEP ) { // // create the event handle // m_OverlappedEvent = new AutoResetEvent(false); // // fill in the overlapped structure with the event handle. // Marshal.WriteIntPtr( m_UnmanagedBlob, Win32.OverlappedhEventOffset, m_OverlappedEvent.Handle ); // // Fill in Buffer Array structure that will be used for our send/recv Buffer // m_WSABuffer = new WSABuffer(); m_GCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); m_WSABuffer.Length = size; m_WSABuffer.Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); // // fill in flags if we use it. // m_Flags = socketFlags; // // if needed fill end point // if (remoteEP != null) { m_SocketAddress = remoteEP.Serialize(); if (pinRemoteEP) { m_GCHandleSocketAddress = GCHandle.Alloc(m_SocketAddress.m_Buffer, GCHandleType.Pinned); m_GCHandleSocketAddressSize = GCHandle.Alloc(m_SocketAddress.m_Size, GCHandleType.Pinned); } } } // SetUnmanagedStructures()