DICOM-SCP,可以直接使用的SCP(.net framework 4.6.1以上)控制台接收端
此程序只能运行在.net framework 4.6.1版本上的环境,如果要运行在低版本环境,请看上一篇文档
using System; using System.IO; using System.Text; using System.Threading.Tasks; using FellowOakDicom.Imaging.Codec; using FellowOakDicom.Log; using FellowOakDicom.Network; using System.Configuration; namespace FellowOakDicom.Samples.CStoreSCP { internal class Program { private static readonly string _storagePath = ConfigurationManager.AppSettings["StoragePath"]; private static readonly int _port = int.Parse(ConfigurationManager.AppSettings["Port"]); private static readonly string _calledAE = ConfigurationManager.AppSettings["CalledAE"]; private static void Main(string[] args) { //var url = ConfigurationManager.AppSettings["StoragePath"]; // start DICOM server on port from command line argument or 11112 //var port = args != null && args.Length > 0 && int.TryParse(args[0], out int tmp) ? tmp : 11112; var port = _port; Console.WriteLine($"正在端口上启动C-Store SCP服务器,端口:{port},LocalAE:{_calledAE}"); using (var server = DicomServerFactory.Create<CStoreSCP>(port)) { // end process Console.WriteLine("按<return>结束。。。"); Console.ReadLine(); } } private class CStoreSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider { 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 CStoreSCP(INetworkStream stream, Encoding fallbackEncoding, ILogger log, ILogManager logManager, INetworkManager network, ITranscoderManager transcoder) : base(stream, fallbackEncoding, log, logManager, network, transcoder) { } public Task OnReceiveAssociationRequestAsync(DicomAssociation association) { if (association.CalledAE != _calledAE) { return SendAssociationRejectAsync( DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized); } foreach (var pc in association.PresentationContexts) { if (pc.AbstractSyntax == DicomUID.Verification) { pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes); } else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) { pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes); } } return SendAssociationAcceptAsync(association); } public Task OnReceiveAssociationReleaseRequestAsync() { return SendAssociationReleaseResponseAsync(); } public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason) { /* nothing to do here */ } public void OnConnectionClosed(Exception exception) { /* nothing to do here */ } public async Task<DicomCStoreResponse> OnCStoreRequestAsync(DicomCStoreRequest request) { var studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID).Trim(); var instUid = request.SOPInstanceUID.UID; var path = Path.GetFullPath(Program._storagePath); path = Path.Combine(path, studyUid); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } path = Path.Combine(path, instUid) + ".dcm"; await request.File.SaveAsync(path); return new DicomCStoreResponse(request, DicomStatus.Success); } public Task OnCStoreRequestExceptionAsync(string tempFileName, Exception e) { // let library handle logging and error response return Task.CompletedTask; } public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request) { return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success)); } } } }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="StoragePath" value="MYDICOM/"/> <add key="Port" value="11112"/> <add key="CalledAE" value="STORESCP9230"/> </appSettings> </configuration>