private static int ReceiveMessageAndFileDescriptor( this Socket socket, Span <byte> buffer, out IntPtr fileDescriptor) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } unsafe { fixed(byte *pinnedData = &buffer.GetPinnableReference()) { // Message data. // IoVec ioVec = default; ioVec.IovBase = new IntPtr(pinnedData); ioVec.IovLength = (ulong)buffer.Length; // #define SOL_SOCKET 1 ControlMessage <int> controlMessage = default; controlMessage.Header.ControlMessageLength = (ulong)sizeof(ControlMessage <int>); controlMessage.Header.ControlMessageLevel = 1; controlMessage.Header.ControlMessageType = SocketLevelMessageType.ScmRights; controlMessage.Value = 0; // Construct the message. // MessageHeader message = default; message.MessageName = IntPtr.Zero; message.MessageNameLength = 0; message.MessageIoVec = &ioVec; message.MessageIoVecLength = 1; message.MessageControl = &controlMessage.Header; message.MessageControlLength = controlMessage.Header.ControlMessageLength; // Receive the message. // ulong bytesRead = Native.ReceiveMessage(socket.Handle, ref message, 0); if ((long)bytesRead == -1) { throw new SocketException(Marshal.GetLastWin32Error()); } fileDescriptor = new IntPtr(controlMessage.Value); int received = checked ((int)bytesRead); return(received); } } }
/// <summary> /// Receives the message and passed file descriptor. /// </summary> /// <param name="socket"></param> /// <param name="buffer"></param> /// <param name="fileDescriptor"></param> /// <returns></returns> internal static int ReceiveMessageAndFileDescriptor( this Socket socket, out byte[] buffer, out IntPtr fileDescriptor) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } fileDescriptor = Native.InvalidPointer; buffer = null; unsafe { Span <byte> messageSpan = stackalloc byte[256]; fixed(byte *pinnedData = &messageSpan.GetPinnableReference()) { // Message data. // IoVec ioVec = default; ioVec.IovBase = new IntPtr(pinnedData); ioVec.IovLength = (ulong)messageSpan.Length; // #define SOL_SOCKET 1 ControlMessage <int> controlMessage = default; controlMessage.Header.ControlMessageLength = (ulong)sizeof(ControlMessage <int>); controlMessage.Header.ControlMessageLevel = 1; controlMessage.Header.ControlMessageType = SocketLevelMessageType.ScmRights; controlMessage.Value = 0; // Construct the message. // MessageHeader message = default; message.MessageName = IntPtr.Zero; message.MessageNameLength = 0; message.MessageIoVec = &ioVec; message.MessageIoVecLength = 1; message.MessageControl = &controlMessage.Header; message.MessageControlLength = controlMessage.Header.ControlMessageLength; ulong bytesRead = Native.ReceiveMessage(socket.Handle, ref message, 0); if ((long)bytesRead == -1) { throw new SocketException(Marshal.GetLastWin32Error()); } int messageSize = checked ((int)bytesRead); if (messageSize != 0) { if (message.MessageControlLength != 0) { fileDescriptor = new IntPtr(controlMessage.Value); } buffer = messageSpan.Slice(0, messageSize).ToArray(); } return(messageSize); } } }
private static int SendMessageAndFileDescriptor( this Socket socket, ReadOnlySpan <byte> messageData, IntPtr fileDescriptor) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } if (fileDescriptor == null) { throw new ArgumentNullException(nameof(fileDescriptor)); } unsafe { fixed(byte *pinnedData = &messageData.GetPinnableReference()) { // Message data. // IoVec ioVec = default; ioVec.IovBase = new IntPtr(pinnedData); ioVec.IovLength = (ulong)messageData.Length; // Construct the message. // MessageHeader message = default; message.MessageName = IntPtr.Zero; message.MessageNameLength = 0; message.MessageIoVec = &ioVec; message.MessageIoVecLength = 1; // Control message. // ControlMessage <int> controlMessage = default; if (fileDescriptor != Native.InvalidPointer) { // #define SOL_SOCKET 1 controlMessage.Header.ControlMessageLength = (ulong)sizeof(ControlMessage <int>); controlMessage.Header.ControlMessageLevel = 1; controlMessage.Header.ControlMessageType = SocketLevelMessageType.ScmRights; controlMessage.Value = fileDescriptor.ToInt32(); message.MessageControl = &controlMessage.Header; message.MessageControlLength = controlMessage.Header.ControlMessageLength; } // Send the message. // ulong bytesSent = Native.SendMessage(socket.Handle, ref message, 0); if ((long)bytesSent == -1) { throw new SocketException(Marshal.GetLastWin32Error()); } int sent = checked ((int)bytesSent); return(sent); } } }