示例#1
0
        public async Task Send_PrivateRegisteredSOPClass_SendSucceeds()
        {
            var uid = new DicomUID("1.1.1.1", "Private Fo-Dicom Storage", DicomUidType.SOPClass);

            DicomUID.Register(uid);
            var ds = new DicomDataset(
                new DicomUniqueIdentifier(DicomTag.SOPClassUID, uid),
                new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.4.5"));

            var port = Ports.GetNext();

            using (DicomServerFactory.Create <SimpleCStoreProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                DicomStatus status  = null;
                var         request = new DicomCStoreRequest(new DicomFile(ds))
                {
                    OnResponseReceived = (req, res) => status = res.Status
                };

                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix("DicomClient");
                await client.AddRequestAsync(request);

                await client.SendAsync();

                Assert.Equal(DicomStatus.Success, status);
            }
        }
示例#2
0
        private static async Task <List <DicomDataset> > GetAllItemsFromWorklistAsync(string serverIP, int serverPort, string serverAET, string clientAET)
        {
            var worklistItems = new List <DicomDataset>();
            var cfind         = DicomCFindRequest.CreateWorklistQuery(); // no filter, so query all awailable entries

            cfind.OnResponseReceived = (DicomCFindRequest rq, DicomCFindResponse rp) =>
            {
                if (rp.HasDataset)
                {
                    Console.WriteLine("Study UID: {0}", rp.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));
                    worklistItems.Add(rp.Dataset);
                }
                else
                {
                    Console.WriteLine(rp.Status.ToString());
                }
            };

            var client = DicomClientFactory.Create(serverIP, serverPort, false, clientAET, serverAET);
            await client.AddRequestAsync(cfind);

            await client.SendAsync();

            return(worklistItems);
        }
示例#3
0
        public async Task Create_SubclassedServer_SufficientlyCreated()
        {
            var port = Ports.GetNext();

            using var server = DicomServerFactory.Create <DicomCEchoProvider, DicomCEchoProviderServer>(null, port, logger: _logger.IncludePrefix("DicomServer"));

            Assert.IsType <DicomCEchoProviderServer>(server);
            Assert.Equal(DicomServerRegistry.Get(port)?.DicomServer, server);

            var status = DicomStatus.UnrecognizedOperation;
            var handle = new ManualResetEventSlim();

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = _logger.IncludePrefix("DicomClient");
            await client.AddRequestAsync(new DicomCEchoRequest
            {
                OnResponseReceived = (req, rsp) =>
                {
                    status = rsp.Status;
                    handle.Set();
                }
            });

            await client.SendAsync();

            handle.Wait(1000);
            Assert.Equal(DicomStatus.Success, status);
        }
示例#4
0
        public async Task DicomClientSend_ToRejectedAssociation_ShouldNotSendRequest()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <DicomClientTest.MockCEchoProvider>(port))
            {
                var         locker = new object();
                DicomStatus status = null;

                var client = DicomClientFactory.Create("localhost", port, false, "SCU", "WRONG-SCP");
                await client.AddRequestAsync(
                    new DicomCEchoRequest
                {
                    OnResponseReceived = (rq, rsp) =>
                    {
                        lock (locker) status = rsp.Status;
                    }
                }).ConfigureAwait(false);

                try
                {
                    await client.SendAsync().ConfigureAwait(false);
                }
                catch
                {
                }

                Assert.Null(status);
            }
        }
示例#5
0
        public async Task DicomClientSend_ToAcceptedAssociation_ShouldSendRequest()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <DicomClientTest.MockCEchoProvider>(port))
            {
                var locker = new object();

                var         expected = DicomStatus.Success;
                DicomStatus actual   = null;

                var client = DicomClientFactory.Create("localhost", port, false, "SCU", "ANY-SCP");
                await client.AddRequestAsync(
                    new DicomCEchoRequest
                {
                    OnResponseReceived = (rq, rsp) =>
                    {
                        lock (locker) actual = rsp.Status;
                    }
                }).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Equal(expected, actual);
            }
        }
        public async Task OnCStoreRequestAsync_PreferedTransfersyntax()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <AsyncDicomCStoreProviderPreferingUncompressedTS>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                int numberOfContexts           = 0;
                DicomTransferSyntax accpetedTS = null;
                // create a request with a jpeg-encoded file
                var request = new DicomCStoreRequest(TestData.Resolve("CT1_J2KI"));
                client.AssociationAccepted += (sender, e) =>
                {
                    numberOfContexts = e.Association.PresentationContexts.Count;
                    accpetedTS       = e.Association.PresentationContexts.First().AcceptedTransferSyntax;
                };
                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Equal(2, numberOfContexts); // one for the jpeg2k TS and one for the mandatory ImplicitLittleEndian
                Assert.Equal(DicomTransferSyntax.JPEG2000Lossy, accpetedTS);
            }
        }
        public async Task OnCGetRequestAsync_Pending_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <PendingAsyncDicomCGetProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                var responses = new ConcurrentQueue <DicomCGetResponse>();
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var studyInstanceUID = DicomUIDGenerator.GenerateDerivedFromUUID().ToString();
                var request          = new DicomCGetRequest(studyInstanceUID)
                {
                    OnResponseReceived = (req, res) => responses.Enqueue(res),
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Collection(
                    responses,
                    response1 => Assert.Equal(DicomStatus.Pending, response1.Status),
                    response2 => Assert.Equal(DicomStatus.Pending, response2.Status),
                    response3 => Assert.Equal(DicomStatus.Success, response3.Status)
                    );
                Assert.Null(timeout);
            }
        }
        public async Task AcceptStoreContexts()
        {
            int port = Ports.GetNext();

            using (DicomServerFactory.Create <AcceptOnlyEchoStoreProvider>(port))
            {
                var         echoReq    = new DicomCEchoRequest();
                DicomStatus echoStatus = DicomStatus.Pending;
                echoReq.OnResponseReceived += (req, resp) => echoStatus = resp.Status;

                var         storeReq    = new DicomCStoreRequest(TestData.Resolve("CT1_J2KI"));
                DicomStatus storeStatus = DicomStatus.Pending;
                storeReq.OnResponseReceived += (req, resp) => storeStatus = resp.Status;

                var         filmSession = new FilmSession(DicomUID.BasicFilmSession, DicomUID.Generate());
                var         printReq    = new DicomNCreateRequest(filmSession.SOPClassUID, filmSession.SOPInstanceUID);
                DicomStatus printStatus = DicomStatus.Pending;
                printReq.OnResponseReceived += (req, resp) => printStatus = resp.Status;

                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                await client.AddRequestsAsync(new DicomRequest[] { echoReq, storeReq, printReq });

                await client.SendAsync();

                Assert.Equal(DicomStatus.Success, echoStatus);
                Assert.Equal(DicomStatus.Success, storeStatus);
                Assert.Equal(DicomStatus.SOPClassNotSupported, printStatus);
            }
        }
示例#9
0
        public async Task CStoreRequestSend_VideoFileServerSupportsMPEG4_TransferSuccessful()
        {
            string fileName = TestData.Resolve("test_720.dcm");
            var    success  = false;
            var    handle   = new ManualResetEventSlim();

            var port = Ports.GetNext();

            using var server = DicomServerFactory.Create <VideoCStoreProvider>(port);
            server.Logger    = _logger.IncludePrefix("VideoCStoreProvider");

            var request = new DicomCStoreRequest(fileName)
            {
                OnResponseReceived = (req, rsp) =>
                {
                    success = req.Dataset.InternalTransferSyntax.Equals(
                        DicomTransferSyntax.Lookup(DicomUID.MPEG4HP41)) &&
                              rsp.Status == DicomStatus.Success;
                    handle.Set();
                }
            };

            var client = DicomClientFactory.Create("localhost", port, false, "STORESCU", "STORESCP");

            client.Logger = _logger.IncludePrefix("DicomClient");

            await client.AddRequestAsync(request).ConfigureAwait(false);

            await client.SendAsync().ConfigureAwait(false);

            handle.Wait(10000);

            Assert.True(success);
        }
示例#10
0
        public async Task CStoreRequestSend_VideoFileServerSupportsMPEG2_TransferSuccessful()
        {
            string fileName = TestData.Resolve("ETIAM_video_002.dcm");

            var success = false;
            var handle  = new ManualResetEventSlim();

            var port = Ports.GetNext();

            using (DicomServerFactory.Create <VideoCStoreProvider>(port))
            {
                var request = new DicomCStoreRequest(fileName);
                request.OnResponseReceived = (req, rsp) =>
                {
                    success = req.Dataset.InternalTransferSyntax.Equals(DicomTransferSyntax.MPEG2) &&
                              rsp.Status == DicomStatus.Success;
                    handle.Set();
                };

                var client = DicomClientFactory.Create("localhost", port, false, "STORESCU", "STORESCP");
                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                handle.Wait(10000);

                Assert.True(success);
            }
        }
示例#11
0
        public async Task CStoreRequestSend_16BitJpegFileToScpThatDoesNotSupportJpeg_TransferSuccessfulImplicitLENoPixelData()
        {
            string file    = TestData.Resolve("GH538-jpeg14sv1.dcm");
            var    handle  = new ManualResetEventSlim();
            var    success = false;

            var port = Ports.GetNext();

            using (DicomServerFactory.Create <VideoCStoreProvider>(port))
            {
                var request = new DicomCStoreRequest(file)
                {
                    OnResponseReceived = (req, rsp) =>
                    {
                        if (req.Dataset.InternalTransferSyntax.Equals(DicomTransferSyntax.ImplicitVRLittleEndian) &&
                            req.Dataset.Contains(DicomTag.PixelData) && rsp.Status == DicomStatus.Success)
                        {
                            success = true;
                        }

                        handle.Set();
                    }
                };

                var client = DicomClientFactory.Create("localhost", port, false, "STORESCU", "STORESCP");
                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                handle.Wait(10000);

                Assert.True(success);
            }
        }
示例#12
0
        public async Task OnCEchoRequestAsync_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <AsyncDicomCEchoProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                DicomCEchoResponse response             = null;
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var request = new DicomCEchoRequest
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.NotNull(response);
                Assert.Equal(DicomStatus.Success, response.Status);
                Assert.Null(timeout);
            }
        }
        private IDicomClient CreateClient(int port)
        {
            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name).WithMinimumLevel(LogLevel.Debug);
            return(client);
        }
示例#14
0
        public async Task SendAsync_SingleRequest_DataSufficientlyTransported()
        {
            int port = Ports.GetNext();

            using var _ = DicomServerFactory.Create <SimpleCStoreProvider>(port);

            DicomDataset command = null, dataset = null;
            var          request = new DicomCStoreRequest(TestData.Resolve("CT1_J2KI"));

            request.OnResponseReceived = (req, res) =>
            {
                command = request.Command;
                dataset = request.Dataset;
            };

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
            await client.AddRequestAsync(request).ConfigureAwait(false);

            await client.SendAsync().ConfigureAwait(false);

            var commandField = command.GetSingleValue <ushort>(DicomTag.CommandField);

            Assert.Equal((ushort)1, commandField);

            var modality = dataset.GetSingleValue <string>(DicomTag.Modality);

            Assert.Equal("CT", modality);
        }
示例#15
0
        public async Task Stop_DisconnectedClientsCount_ShouldBeZeroAfterShortDelay()
        {
            var port = Ports.GetNext();

            using var server = DicomServerFactory.Create <DicomCEchoProvider>(port, logger: _logger.IncludePrefix("DicomServer"));
            while (!server.IsListening)
            {
                Thread.Sleep(10);
            }

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = _logger.IncludePrefix("DicomClient");
            await client.AddRequestAsync(new DicomCEchoRequest());

            await client.SendAsync();

            Thread.Sleep(100);

            server.Stop();
            Thread.Sleep(100);

            var actual = ((DicomServer <DicomCEchoProvider>)server).CompletedServicesCount;

            Assert.Equal(0, actual);
        }
示例#16
0
        public async Task Print()
        {
            var dicomClient = DicomClientFactory.Create(RemoteAddress, RemotePort, false, CallingAE, CalledAE);

            await dicomClient.AddRequestAsync(
                new DicomNCreateRequest(FilmSession.SOPClassUID, FilmSession.SOPInstanceUID)
            {
                Dataset = FilmSession
            });


            foreach (var filmbox in FilmSession.BasicFilmBoxes)
            {
                var imageBoxRequests = new List <DicomNSetRequest>();

                var filmBoxRequest = new DicomNCreateRequest(FilmBox.SOPClassUID, filmbox.SOPInstanceUID)
                {
                    Dataset = filmbox
                };
                filmBoxRequest.OnResponseReceived = (request, response) =>
                {
                    if (response.HasDataset)
                    {
                        var seq = response.Dataset.GetSequence(DicomTag.ReferencedImageBoxSequence);
                        for (int i = 0; i < seq.Items.Count; i++)
                        {
                            var req            = imageBoxRequests[i];
                            var imageBox       = req.Dataset;
                            var sopInstanceUid = seq.Items[i].GetSingleValue <string>(DicomTag.ReferencedSOPInstanceUID);
                            imageBox.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstanceUid);
                            req.Command.AddOrUpdate(DicomTag.RequestedSOPInstanceUID, sopInstanceUid);
                        }
                    }
                };
                await dicomClient.AddRequestAsync(filmBoxRequest);

                foreach (var image in filmbox.BasicImageBoxes)
                {
                    var req = new DicomNSetRequest(image.SOPClassUID, image.SOPInstanceUID)
                    {
                        Dataset = image
                    };

                    imageBoxRequests.Add(req);
                    await dicomClient.AddRequestAsync(req);
                }
            }

            await dicomClient.AddRequestAsync(new DicomNActionRequest(FilmSession.SOPClassUID, FilmSession.SOPInstanceUID, 0x0001));

            await dicomClient.SendAsync();
        }
        public void CreateDicomClient_CreatesNewInstanceOfDicomClient()
        {
            // Arrange
            var mockProvider = new MockProvider();
            var clientFactory = new DicomClientFactory<TestInfo>(mockProvider.GetSettingsProviderFake(), mockProvider.GetRequestAdapterFake());

            // Act
            var client1 = clientFactory.CreateDicomClient();
            var client2 = clientFactory.CreateDicomClient();

            // Assert
            Assert.That(client1, Is.Not.SameAs(client2));
        }
示例#18
0
        public async Task Send_PrivateTags_DataSufficientlyTransported()
        {
            var port = Ports.GetNext();

            using var _ = DicomServerFactory.Create <SimpleCStoreProvider>(port);

            DicomDataset command = null, requestDataset = null, responseDataset = null;
            var          request = new DicomCStoreRequest(new DicomDataset
            {
                { DicomTag.CommandField, (ushort)DicomCommandField.CStoreRequest },
                { DicomTag.AffectedSOPClassUID, DicomUID.CTImageStorage },
                { DicomTag.MessageID, (ushort)1 },
                { DicomTag.AffectedSOPInstanceUID, "1.2.3" },
            });

            var privateCreator = DicomDictionary.Default.GetPrivateCreator("Testing");
            var privTag1       = new DicomTag(4013, 0x008, privateCreator);
            var privTag2       = new DicomTag(4013, 0x009, privateCreator);

            DicomDictionary.Default.Add(new DicomDictionaryEntry(privTag1, "testTag1", "testKey1", DicomVM.VM_1, false, DicomVR.CS));
            DicomDictionary.Default.Add(new DicomDictionaryEntry(privTag2, "testTag2", "testKey2", DicomVM.VM_1, false, DicomVR.CS));

            request.Dataset = new DicomDataset
            {
                { DicomTag.Modality, "CT" },
                { privTag1, "TESTA" },
                new DicomCodeString(privTag2, "TESTB")
            };

            request.OnResponseReceived = (req, res) =>
            {
                command         = req.Command;
                requestDataset  = req.Dataset;
                responseDataset = res.Dataset;
            };

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
            await client.AddRequestAsync(request).ConfigureAwait(false);

            await client.SendAsync().ConfigureAwait(false);

            Assert.Equal((ushort)1, command.GetSingleValue <ushort>(DicomTag.CommandField));

            Assert.Equal("CT", requestDataset.GetString(DicomTag.Modality));
            Assert.Equal("TESTB", requestDataset.GetSingleValueOrDefault <string>(privTag2, null));
            Assert.Equal("TESTA", requestDataset.GetSingleValueOrDefault <string>(privTag1, null));

            Assert.Equal("CT", responseDataset.GetSingleValue <string>(DicomTag.Modality));
            Assert.Equal("TESTB", responseDataset.GetValueOrDefault <string>(privTag2, 0, null));
            Assert.Equal("TESTA", responseDataset.GetSingleValueOrDefault <string>(privTag1, null));
        }
示例#19
0
        public async Task DicomService_reading_messages_with_invalid_UIDs_does_not_fail()
        {
            int port         = Ports.GetNext();
            var clientLogger = _output.IncludePrefix(nameof(DicomClient));
            var serverLogger = _output.IncludePrefix(nameof(DicomCEchoProvider));
            var source       = new CancellationTokenSource();

            using var server                = DicomServerFactory.Create <SimpleCStoreProvider>(port, logger: serverLogger);
            server.Options.LogDataPDUs      = true;
            server.Options.LogDimseDatasets = true;

            while (!server.IsListening)
            {
                await Task.Delay(50);
            }

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = clientLogger;

            var command = new DicomDataset
            {
                ValidateItems = false
            };

            command.Add(DicomTag.CommandField, (ushort)DicomCommandField.CStoreRequest);
            command.Add(DicomTag.MessageID, (ushort)1);
            command.Add(DicomTag.AffectedSOPClassUID, DicomUID.CTImageStorage);
            command.Add(new DicomUniqueIdentifier(DicomTag.AffectedSOPInstanceUID, "1.2.3.04"));

            var request = new DicomCStoreRequest(command)
            {
                File    = new DicomFile(),
                Dataset = new DicomDataset()
            };

            request.Dataset.ValidateItems = false;
            request.Dataset.Add(DicomTag.SOPClassUID, DicomUID.CTImageStorage);
            request.Dataset.Add(new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.04"));

            request.OnResponseReceived += (e, args) =>
            {
                _output.Info("Response received. Cancelling in 500ms.");
                source.CancelAfter(100);
            };

            await client.AddRequestAsync(request);

            await client.SendAsync();
        }
示例#20
0
        public async Task CStoreRequestSend_8And16BitJpegFiles_TransferSuccessful()
        {
            string file1     = TestData.Resolve("GH538-jpeg1.dcm");
            string file2     = TestData.Resolve("GH538-jpeg14sv1.dcm");
            var    handle1   = new ManualResetEventSlim();
            var    handle2   = new ManualResetEventSlim();
            var    successes = 0;

            var port = Ports.GetNext();

            using (DicomServerFactory.Create <SimpleCStoreProvider>(port))
            {
                var request1 = new DicomCStoreRequest(file1);
                request1.OnResponseReceived = (req, rsp) =>
                {
                    if (req.Dataset.InternalTransferSyntax.Equals(DicomTransferSyntax.JPEGProcess1) &&
                        rsp.Status == DicomStatus.Success)
                    {
                        ++successes;
                    }

                    handle1.Set();
                };

                var request2 = new DicomCStoreRequest(file2);
                request2.OnResponseReceived = (req, rsp) =>
                {
                    if (req.Dataset.InternalTransferSyntax.Equals(DicomTransferSyntax.JPEGProcess14SV1) &&
                        rsp.Status == DicomStatus.Success)
                    {
                        ++successes;
                    }

                    handle2.Set();
                };

                var client = DicomClientFactory.Create("localhost", port, false, "STORESCU", "STORESCP");
                await client.AddRequestAsync(request1).ConfigureAwait(false);

                await client.AddRequestAsync(request2).ConfigureAwait(false);

                await client.SendAsync();

                handle1.Wait(10000);
                handle2.Wait(10000);

                Assert.Equal(2, successes);
            }
        }
示例#21
0
        public async Task Send_FromIpv6ToIpv4AnyListenerKnownSOPClass_SendFails()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <SimpleCStoreProvider>(NetworkManager.IPv4Any, port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var request = new DicomCStoreRequest(TestData.Resolve("CT-MONO2-16-ankle"));

                var client = DicomClientFactory.Create(NetworkManager.IPv6Loopback, port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix("DicomClient");
                await client.AddRequestAsync(request);

                var exception = await Record.ExceptionAsync(async() => await client.SendAsync());

                Assert.NotNull(exception);
            }
        }
示例#22
0
        public async Task DicomClientShallNotCloseConnectionTooEarly_CEchoSerialAsync(int expected)
        {
            var port         = Ports.GetNext();
            var testLogger   = _logger.IncludePrefix("GH745");
            var clientLogger = _logger.IncludePrefix(nameof(DicomClient));
            var serverLogger = _logger.IncludePrefix(nameof(DicomCEchoProvider));

            using var server = DicomServerFactory.Create <DicomCEchoProvider>(port);
            server.Logger    = serverLogger;
            while (!server.IsListening)
            {
                await Task.Delay(50);
            }

            var actual = 0;

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = clientLogger;
            client.ClientOptions.AssociationRequestTimeoutInMs = 600 * 1000;
            client.ClientOptions.AssociationLingerTimeoutInMs  = 1; // No need to linger, we only send one request at a time

            for (var i = 0; i < expected; i++)
            {
                await client.AddRequestAsync(
                    new DicomCEchoRequest
                {
                    OnResponseReceived = (req, res) =>
                    {
                        testLogger.Info("Response #{0} / expected #{1}", actual, req.UserState);
                        Interlocked.Increment(ref actual);
                        testLogger.Info("         #{0} / expected #{1}", actual - 1, req.UserState);
                    },
                    UserState = i
                }
                    ).ConfigureAwait(false);

                testLogger.Info("Sending #{0}", i);
                await client.SendAsync().ConfigureAwait(false);

                testLogger.Info("Sent (or timed out) #{0}", i);
            }

            Assert.Equal(expected, actual);
        }
示例#23
0
        public async Task DicomClientShallNotCloseConnectionTooEarly_CEchoParallelAsync(int expected)
        {
            int port = Ports.GetNext();

            var testLogger   = _logger.IncludePrefix("GH745");
            var clientLogger = _logger.IncludePrefix(nameof(DicomClient));
            var serverLogger = _logger.IncludePrefix(nameof(DicomCEchoProvider));

            using var server = DicomServerFactory.Create <DicomCEchoProvider>(port);
            server.Logger    = serverLogger;
            while (!server.IsListening)
            {
                await Task.Delay(50);
            }

            var actual = 0;

            var requests = Enumerable.Range(0, expected).Select(
                async requestIndex =>
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.ClientOptions.AssociationRequestTimeoutInMs = 600 * 1000;
                client.Logger = clientLogger;

                await client.AddRequestAsync(
                    new DicomCEchoRequest
                {
                    OnResponseReceived = (req, res) =>
                    {
                        testLogger.Info("Response #{0}", requestIndex);
                        Interlocked.Increment(ref actual);
                    }
                }
                    ).ConfigureAwait(false);

                testLogger.Info("Sending #{0}", requestIndex);
                await client.SendAsync().ConfigureAwait(false);
                testLogger.Info("Sent (or timed out) #{0}", requestIndex);
            }
                ).ToArray();

            await Task.WhenAll(requests).ConfigureAwait(false);

            Assert.Equal(expected, actual);
        }
示例#24
0
        public async Task OldDicomClientSend_StorePart10File_ShouldSucceed()
        {
            var port = Ports.GetNext();

            using var server = DicomServerFactory.Create <CStoreScp>(port);
            server.Logger    = _logger.IncludePrefix("CStoreScp");

            var file = DicomFile.Open(TestData.Resolve("CT-MONO2-16-ankle"));

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "SCP");

            client.Logger = _logger.IncludePrefix("DicomClient");
            await client.AddRequestAsync(new DicomCStoreRequest(file));

            var exception = await Record.ExceptionAsync(() => client.SendAsync());

            Assert.Null(exception);
        }
示例#25
0
        public async Task Send_FromDicomClient_DoesNotDeadlock()
        {
            var port = Ports.GetNext();

            using var server = DicomServerFactory.Create <DicomCEchoProvider>(port);

            server.Logger = new XUnitDicomLogger(_output).IncludeTimestamps().IncludeThreadId().IncludePrefix("DicomCEchoProvider");
            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.Logger = new XUnitDicomLogger(_output).IncludeTimestamps().IncludeThreadId().IncludePrefix("DicomClient");

            for (var i = 0; i < 10; i++)
            {
                await client.AddRequestAsync(new DicomCEchoRequest()).ConfigureAwait(false);
            }

            await client.SendAsync().ConfigureAwait(false);

            Assert.False(client.IsSendRequired);
        }
示例#26
0
        public async Task DicomClientSend_TooManyPresentationContexts_YieldsInformativeException()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <DicomCEchoProvider>(port))
            {
                var client = DicomClientFactory.Create("localhost", port, false, "SCU", "SCP");

                // this just illustrates the issue of too many presentation contexts, not real world application.
                var pcs =
                    DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                        DicomStorageCategory.None,
                        DicomTransferSyntax.ImplicitVRLittleEndian);

                client.AdditionalPresentationContexts.AddRange(pcs);

                var exception = await Record.ExceptionAsync(() => client.SendAsync());

                Assert.IsType <DicomNetworkException>(exception);
            }
        }
示例#27
0
        public async Task Send_LoopbackListenerKnownSOPClass_SendSucceeds()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <SimpleCStoreProvider>(NetworkManager.IPv4Loopback, port, logger: _logger.IncludePrefix("DicomServer")))
            {
                DicomStatus status  = null;
                var         request = new DicomCStoreRequest(TestData.Resolve("CT-MONO2-16-ankle"))
                {
                    OnResponseReceived = (req, res) => status = res.Status
                };

                var client = DicomClientFactory.Create(NetworkManager.IPv4Loopback, port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix("DicomClient");
                await client.AddRequestAsync(request);

                await client.SendAsync();

                Assert.Equal(DicomStatus.Success, status);
            }
        }
示例#28
0
        public async Task DicomCGetRequest_PickCTImagesInStudy_OnlyCTImagesRetrieved()
        {
            var client = DicomClientFactory.Create("localhost", 11112, false, "SCU", "COMMON");

            var pc = DicomPresentationContext.GetScpRolePresentationContext(DicomUID.CTImageStorage);

            client.AdditionalPresentationContexts.Add(pc);

            var counter = 0;
            var locker  = new object();

            client.OnCStoreRequest = request =>
            {
                lock (locker)
                {
                    ++counter;
                }

                return(Task.FromResult(new DicomCStoreResponse(request, DicomStatus.Success)));
            };

            var get = new DicomCGetRequest("1.2.840.113619.2.55.3.2609388324.145.1222836278.84");

            var handle = new ManualResetEventSlim();

            get.OnResponseReceived = (request, response) =>
            {
                if (response.Remaining == 0)
                {
                    handle.Set();
                }
            };
            await client.AddRequestAsync(get);

            await client.SendAsync().ConfigureAwait(false);

            handle.Wait();

            Assert.Equal(140, counter);
        }
示例#29
0
        public async Task SendMaxPDU()
        {
            var  port            = Ports.GetNext();
            uint serverPduLength = 400000;
            uint clientPduLength = serverPduLength / 2;

            using var server            = DicomServerFactory.Create <DicomCEchoProvider>(port);
            server.Options.MaxPDULength = serverPduLength;

            var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");

            client.ServiceOptions.MaxPDULength = clientPduLength; // explicitly choose a different value
            await client.AddRequestAsync(new DicomCEchoRequest());

            uint serverPduInAssociationAccepted = 0;

            client.AssociationAccepted += (sender, e) => serverPduInAssociationAccepted = e.Association.MaximumPDULength;

            await client.SendAsync();

            Assert.Equal(serverPduLength, serverPduInAssociationAccepted);
        }
示例#30
0
        public async Task DicomCGetRequest_OneImageInSeries_Received()
        {
            var client = DicomClientFactory.Create("localhost", 11112, false, "SCU", "COMMON");

            var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                DicomStorageCategory.Image,
                DicomTransferSyntax.ExplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRBigEndian);

            client.AdditionalPresentationContexts.AddRange(pcs);

            DicomDataset dataset = null;

            client.OnCStoreRequest = request =>
            {
                dataset = request.Dataset;
                return(Task.FromResult(new DicomCStoreResponse(request, DicomStatus.Success)));
            };

            var get = new DicomCGetRequest(
                "1.2.840.113619.2.1.1.322987881.621.736170080.681",
                "1.2.840.113619.2.1.2411.1031152382.365.736169244");

            var handle = new ManualResetEventSlim();

            get.OnResponseReceived = (request, response) =>
            {
                handle.Set();
            };
            await client.AddRequestAsync(get);

            await client.SendAsync().ConfigureAwait(false);

            handle.Wait();

            Assert.Equal("RT ANKLE", dataset.GetString(DicomTag.StudyDescription));
        }
示例#31
0
        static async Task Main(string[] args)
        {
            var storeMore = "";

            _storeServerHost = GetServerHost();
            _storeServerPort = GetServerPort();

            Console.WriteLine("***************************************************");
            Console.WriteLine("Server AE Title: " + _storeServerAET);
            Console.WriteLine("Server Host Address: " + _storeServerHost);
            Console.WriteLine("Server Port: " + _storeServerPort);
            Console.WriteLine("Client AE Title: " + _aet);
            Console.WriteLine("***************************************************");

            var client = DicomClientFactory.Create(_storeServerHost, _storeServerPort, false, _aet, _storeServerAET);

            client.NegotiateAsyncOps();

            do
            {
                try
                {
                    Console.WriteLine();
                    Console.WriteLine("Enter the path for a DICOM file:");
                    Console.Write(">>>");
                    string dicomFile = Console.ReadLine();

                    while (!File.Exists(dicomFile))
                    {
                        Console.WriteLine("Invalid file path, enter the path for a DICOM file or press Enter to Exit:");

                        dicomFile = Console.ReadLine();

                        if (string.IsNullOrWhiteSpace(dicomFile))
                        {
                            return;
                        }
                    }

                    var request = new DicomCStoreRequest(dicomFile);

                    request.OnResponseReceived += (req, response) => Console.WriteLine("C-Store Response Received, Status: " + response.Status);

                    await client.AddRequestAsync(request);

                    await client.SendAsync();
                }
                catch (Exception exception)
                {
                    Console.WriteLine();
                    Console.WriteLine("----------------------------------------------------");
                    Console.WriteLine("Error storing file. Exception Details:");
                    Console.WriteLine(exception.ToString());
                    Console.WriteLine("----------------------------------------------------");
                    Console.WriteLine();
                }

                Console.WriteLine("To store another file, enter \"y\"; Othersie, press enter to exit: ");
                Console.Write(">>>");
                storeMore = Console.ReadLine().Trim();
            } while (storeMore.Length > 0 && storeMore.ToLower()[0] == 'y');
        }