private PDUBase SendReceivePDU(PDUBase send_pdu) { try { CallId++; PDUHeader pdu_header = new PDUHeader() { MajorVersion = PDUHeader.RPC_VERSION_MAJOR, MinorVersion = PDUHeader.RPC_VERSION_MINOR, DataRep = _data_rep, CallId = CallId, Type = send_pdu.PDUType }; List <byte[]> fragments = send_pdu.DoFragment(_max_send_fragment - PDUHeader.PDU_HEADER_SIZE); for (int i = 0; i < fragments.Count; ++i) { pdu_header.Flags = send_pdu.GetFlags(); if (i == 0) { pdu_header.Flags |= PDUFlags.FirstFrag; } if (i == fragments.Count - 1) { pdu_header.Flags |= PDUFlags.LastFrag; } pdu_header.FragmentLength = (ushort)(fragments[i].Length + PDUHeader.PDU_HEADER_SIZE); MemoryStream send_stm = new MemoryStream(); BinaryWriter writer = new BinaryWriter(send_stm); pdu_header.Write(writer); writer.Write(fragments[i]); byte[] fragment = send_stm.ToArray(); string name = fragments.Count == 1 ? "RPC Named Pipe Send Buffer" : $"RPC Named Pipe Send Buffer - Fragment {i}"; RpcUtils.DumpBuffer(true, name, fragment); if (_pipe.Write(fragment) != fragment.Length) { throw new RpcTransportException("Failed to write out PDU buffer."); } } MemoryStream recv_stm = new MemoryStream(); PDUHeader curr_header = new PDUHeader(); int frag_count = 0; while ((curr_header.Flags & PDUFlags.LastFrag) == 0) { var pdu = ReadPDU(frag_count++); curr_header = pdu.Item1; if (curr_header.CallId != CallId) { throw new RpcTransportException("Mismatching call ID."); } recv_stm.Write(pdu.Item2, 0, pdu.Item2.Length); } return(CheckFault(curr_header.ToPDU(recv_stm.ToArray()))); } catch (EndOfStreamException) { throw new RpcTransportException("End of stream."); } }
/// <summary> /// Write the fragment to the transport. /// </summary> /// <param name="fragment">The fragment to write.</param> /// <returns>True if successfully wrote the fragment.</returns> protected override bool WriteFragment(byte[] fragment) { return(_pipe.Write(fragment) == fragment.Length); }