Closed MarcoK80 closed 2 years ago
Hi, since version 5.0.2 (works in version 5.0.0) a normal C-Echo to a test server do not return and the server shows:
[DEBUG] [IDLE] --> [CONNECTING] [DEBUG] [CONNECTING] --> [REQUESTING ASSOCIATION] [INFO] PluginAET -> Association request: Calling AE Title: ReceiverPluginAET Called AE Title: PluginAET Remote host: localhost Remote port: 1234 Implementation Class: Implementation Class UID [1.3.6.1.4.1.30071.8] Implementation Version: fo-dicom 5.0.2 Maximum PDU Length: 0 Async Ops Invoked: 0 Async Ops Performed: 0 Presentation Contexts: 1 Presentation Context: 1 [Proposed] Abstract Syntax: Verification SOP Class Transfer Syntax: Implicit VR Little Endian: Default Transfer Syntax for DICOM [ERROR] Exception processing PDU: FellowOakDicom.Network.DicomNetworkException: Pdu[type=01, length=211] (offset=211, bytes=1, field="Item-Type") Requested offset out of range! at FellowOakDicom.Network.RawPDU.CheckOffset(Int32 bytes, String name) at FellowOakDicom.Network.RawPDU.ReadByte(String name) at FellowOakDicom.Network.AAssociateRQ.Read(RawPDU raw) at FellowOakDicom.Network.DicomService.d__71.MoveNext() [INFO] Connection closed
Code used for client:
var dicomClient = DicomClientFactory.Create(myPluginHostName, myPluginPort, false, myReceiverAET, mypluginAET); dicomClient.NegotiateAsyncOps(); await dicomClient.AddRequestAsync(new DicomCEchoRequest()).ConfigureAwait(false); await dicomClient.SendAsync().ConfigureAwait(false);
ServerCode
public class QRService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider { private static string StoragePath = @".\DICOMStorage"; private static readonly DicomTransferSyntax[] AcceptedTransferSyntaxes = new DicomTransferSyntax[] { DicomTransferSyntax.ExplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian, DicomTransferSyntax.ImplicitVRLittleEndian }; private static readonly DicomTransferSyntax[] AcceptedImageTransferSyntaxes = new DicomTransferSyntax[] { // Lossless DicomTransferSyntax.JPEGLSLossless, DicomTransferSyntax.JPEG2000Lossless, DicomTransferSyntax.JPEGProcess14SV1, DicomTransferSyntax.JPEGProcess14, DicomTransferSyntax.RLELossless, // Lossy DicomTransferSyntax.JPEGLSNearLossless, DicomTransferSyntax.JPEG2000Lossy, DicomTransferSyntax.JPEGProcess1, DicomTransferSyntax.JPEGProcess2_4, // Uncompressed DicomTransferSyntax.ExplicitVRLittleEndian, DicomTransferSyntax.ExplicitVRBigEndian, DicomTransferSyntax.ImplicitVRLittleEndian }; public string CallingAE { get; protected set; } public string CalledAE { get; protected set; } public IPAddress RemoteIP { get; private set; } public QRService(INetworkStream stream, Encoding fallbackEncoding, ILogger logger, ILogManager logManager, INetworkManager networkManager, ITranscoderManager transcoderManager) : base(stream, fallbackEncoding, logger, logManager, networkManager, transcoderManager) { var pi = stream.GetType().GetProperty("Socket", BindingFlags.NonPublic | BindingFlags.Instance); if (pi != null) { var endPoint = ((Socket)pi.GetValue(stream, null)).RemoteEndPoint as IPEndPoint; RemoteIP = endPoint.Address; } else { RemoteIP = new IPAddress(new byte[] { 127, 0, 0, 1 }); } if (!Directory.Exists(StoragePath)) { Directory.CreateDirectory(StoragePath); } } public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request) { Logger.Info($"Received verification request from AE {CallingAE} with IP: {RemoteIP}"); return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success)); } public void OnConnectionClosed(Exception exception) { } public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason) { //log the abort reason Logger.Info($"Received abort from {source}, reason is {reason}"); } public Task OnReceiveAssociationReleaseRequestAsync() { return SendAssociationReleaseResponseAsync(); } public Task OnReceiveAssociationRequestAsync(DicomAssociation association) { CallingAE = association.CallingAE; CalledAE = association.CalledAE; Console.WriteLine($"Received association request from AE: {CallingAE} with IP: {RemoteIP} "); if (QRServer.AETitle != CalledAE) { Logger.Warn($"Association with {CallingAE} rejected since called aet {CalledAE} is unknown"); return SendAssociationRejectAsync(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized); } foreach (var pc in association.PresentationContexts) { if (pc.AbstractSyntax == DicomUID.Verification) { pc.SetResult(DicomPresentationContextResult.Accept); } else if (pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelFind || pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelMove || pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelFind || pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelMove) { Logger.Info($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} supported, using AcceptedTransferSyntaxes"); pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes); } else if (pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelGet || pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelGet) { Logger.Info($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} supported, using AcceptedImageTransferSyntaxes"); pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes); } else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) { Logger.Info($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} supported, using AcceptedImageTransferSyntaxes"); pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes); } else { Logger.Warn($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} not supported"); pc.SetResult(DicomPresentationContextResult.RejectAbstractSyntaxNotSupported); } } Logger.Info($"Accepted association request from {CallingAE}"); return SendAssociationAcceptAsync(association); } public Task<DicomCStoreResponse> OnCStoreRequestAsync(DicomCStoreRequest request) { var studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID); var instUid = request.SOPInstanceUID.UID; var path = Path.GetFullPath(StoragePath); path = Path.Combine(path, studyUid); if (!Directory.Exists(path)) Directory.CreateDirectory(path); path = Path.Combine(path, instUid) + ".dcm"; request.File.Save(path); return Task.FromResult(new DicomCStoreResponse(request, DicomStatus.Success)); } public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e) { // let library handle logging and error response return Task.CompletedTask; } } public static class QRServer { private static IDicomServer _server; public static string AETitle { get; set; } public static void Start(int port, string aet) { AETitle = aet; _server = DicomServerFactory.Create<QRService>(port); } public static void Stop() { _server.Dispose(); } }
Hi, since version 5.0.2 (works in version 5.0.0) a normal C-Echo to a test server do not return and the server shows:
[DEBUG] [IDLE] --> [CONNECTING] [DEBUG] [CONNECTING] --> [REQUESTING ASSOCIATION] [INFO] PluginAET -> Association request: Calling AE Title: ReceiverPluginAET Called AE Title: PluginAET Remote host: localhost Remote port: 1234 Implementation Class: Implementation Class UID [1.3.6.1.4.1.30071.8] Implementation Version: fo-dicom 5.0.2 Maximum PDU Length: 0 Async Ops Invoked: 0 Async Ops Performed: 0 Presentation Contexts: 1 Presentation Context: 1 [Proposed] Abstract Syntax: Verification SOP Class Transfer Syntax: Implicit VR Little Endian: Default Transfer Syntax for DICOM [ERROR] Exception processing PDU: FellowOakDicom.Network.DicomNetworkException: Pdu[type=01, length=211] (offset=211, bytes=1, field="Item-Type") Requested offset out of range! at FellowOakDicom.Network.RawPDU.CheckOffset(Int32 bytes, String name) at FellowOakDicom.Network.RawPDU.ReadByte(String name) at FellowOakDicom.Network.AAssociateRQ.Read(RawPDU raw) at FellowOakDicom.Network.DicomService.d__71.MoveNext()
[INFO] Connection closed
Code used for client:
ServerCode