DICOM-SCP,可以直接使用的SCP(.net framework 4.5)控制台接收端


此程序引用的是Dicom.Core 4.0.8.0,也是最后一版支持部署在.net framework 4.5 或以下环境的。如需要部署在.net4.6.1以上的需要查看另一个文档。

 

  1 using Dicom;
  2 using Dicom.Log;
  3 using Dicom.Network;
  4 using Microsoft.Build.Framework;
  5 using System;
  6 using System.Collections.Generic;
  7 using System.Configuration;
  8 using System.IO;
  9 using System.Linq;
 10 using System.Text;
 11 using System.Threading.Tasks;
 12 
 13 namespace Store_SCP
 14 {
 15     class Program
 16     {
 17         private static readonly string _storagePath = ConfigurationManager.AppSettings["StoragePath"];
 18 
 19         private static readonly int _port = int.Parse(ConfigurationManager.AppSettings["Port"]);
 20 
 21         private static readonly string _calledAE = ConfigurationManager.AppSettings["CalledAE"];
 22 
 23         private static void Main(string[] args)
 24         {
 25             // preload dictionary to prevent timeouts
 26             var dict = DicomDictionary.Default;
 27 
 28             // start DICOM server on port from command line argument or 11112
 29             var port = _port;
 30             Console.WriteLine($"正在端口上启动C-Store SCP服务器,端口:{port},LocalAE:{_calledAE}");
 31 
 32             using (var server = DicomServer.Create<CStoreSCP>(port))
 33             {
 34                 // end process
 35                 Console.WriteLine("Press <return> to end...");
 36                 Console.ReadLine();
 37             }
 38         }
 39 
 40 
 41         private class CStoreSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider
 42         {
 43             private static readonly DicomTransferSyntax[] AcceptedTransferSyntaxes = new DicomTransferSyntax[]
 44             {
 45                DicomTransferSyntax.ExplicitVRLittleEndian,
 46                DicomTransferSyntax.ExplicitVRBigEndian,
 47                DicomTransferSyntax.ImplicitVRLittleEndian
 48             };
 49 
 50             private static readonly DicomTransferSyntax[] AcceptedImageTransferSyntaxes = new DicomTransferSyntax[]
 51             {
 52                // Lossless
 53                DicomTransferSyntax.JPEGLSLossless,
 54                DicomTransferSyntax.JPEG2000Lossless,
 55                DicomTransferSyntax.JPEGProcess14SV1,
 56                DicomTransferSyntax.JPEGProcess14,
 57                DicomTransferSyntax.RLELossless,
 58                // Lossy
 59                DicomTransferSyntax.JPEGLSNearLossless,
 60                DicomTransferSyntax.JPEG2000Lossy,
 61                DicomTransferSyntax.JPEGProcess1,
 62                DicomTransferSyntax.JPEGProcess2_4,
 63                // Uncompressed
 64                DicomTransferSyntax.ExplicitVRLittleEndian,
 65                DicomTransferSyntax.ExplicitVRBigEndian,
 66                DicomTransferSyntax.ImplicitVRLittleEndian
 67             };
 68 
 69             public CStoreSCP(INetworkStream stream, Encoding fallbackEncoding, Logger log)
 70                 : base(stream, fallbackEncoding, log)
 71             {
 72             }
 73 
 74             public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
 75             {
 76                 if (association.CalledAE != _calledAE)
 77                 {
 78                     return SendAssociationRejectAsync(
 79                         DicomRejectResult.Permanent,
 80                         DicomRejectSource.ServiceUser,
 81                         DicomRejectReason.CalledAENotRecognized);
 82                 }
 83 
 84                 foreach (var pc in association.PresentationContexts)
 85                 {
 86                     if (pc.AbstractSyntax == DicomUID.Verification) pc.AcceptTransferSyntaxes(AcceptedTransferSyntaxes);
 87                     else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None) pc.AcceptTransferSyntaxes(AcceptedImageTransferSyntaxes);
 88                 }
 89 
 90                 return SendAssociationAcceptAsync(association);
 91             }
 92 
 93             public Task OnReceiveAssociationReleaseRequestAsync()
 94             {
 95                 return SendAssociationReleaseResponseAsync();
 96             }
 97 
 98             public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
 99             {
100             }
101 
102             public void OnConnectionClosed(Exception exception)
103             {
104             }
105 
106             public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request)
107             {
108                 try
109                 {
110                     var studyUid = request.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID);
111                     var instUid = request.SOPInstanceUID.UID;
112 
113                     var path = Path.GetFullPath(_storagePath);
114                     path = Path.Combine(path, studyUid);
115 
116                     if (!Directory.Exists(path)) Directory.CreateDirectory(path);
117 
118                     path = Path.Combine(path, instUid) + ".dcm";
119 
120                     request.File.Save(path);
121 
122                     LoggerHelper.Instance().Info($"已成功将文件存入到{path}");
123                 }
124                 catch (Exception ex)
125                 {
126 
127                     LoggerHelper.Instance().Info($"文件保存失败,失败原因:{ex.Message}");
128                 }
129                 return new DicomCStoreResponse(request, DicomStatus.Success);
130             }
131 
132             public void OnCStoreRequestException(string tempFileName, Exception e)
133             {
134                 // let library handle logging and error response
135             }
136 
137             public DicomCEchoResponse OnCEchoRequest(DicomCEchoRequest request)
138             {
139                 return new DicomCEchoResponse(request, DicomStatus.Success);
140             }
141         }
142     }
143 
144 }
using System;
using System.Reflection;
using log4net;
using log4net.Config;

namespace Store_SCP
{
    public class LoggerHelper
    {
        private static LoggerHelper _instance = null;
        private static object _locker = new object();
        private ILog _logger;

        private LoggerHelper()
        {
            XmlConfigurator.Configure();
            Type type =MethodBase.GetCurrentMethod().DeclaringType;
            this._logger = LogManager.GetLogger(type);
        }

        public static LoggerHelper Instance()
        {
            if (_instance == null)
            {
                lock (_locker)
                {
                    if (_instance == null)
                    {
                        _instance = new LoggerHelper();
                    }
                }
            }
            return _instance;
        }

        public void Debug(object obj)
        {
            this._logger.Debug(obj);
        }

        public void Error(object obj)
        {
            this._logger.Error(obj);
        }

        public void Fatal(object obj)
        {
            this._logger.Fatal(obj);
        }

        public void Info(object obj)
        {
            this._logger.Info(obj);
        }

        public void Warn(object obj)
        {
            this._logger.Warn(obj);
        }

        public void Debug(object obj, Exception e)
        {
            this._logger.Debug(obj, e);
        }

        public void Error(object obj, Exception e)
        {
            this._logger.Error(obj, e);
        }

        public void Fatal(object obj, Exception e)
        {
            this._logger.Fatal(obj, e);
        }

        public void Info(object obj, Exception e)
        {
            this._logger.Info(obj, e);
        }

        public void Warn(object obj, Exception e)
        {
            this._logger.Warn(obj, e);
        }

    }
}
此是app.config文件
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" > <file value="Logs/" /> <appendToFile value="true" /> <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date"/> <!--这是按日期产生文件夹--> <datePattern value="yyyyMM\\yyyyMMdd'.txt'"/> <!--是否只写到一个文件中--> <staticLogFileName value="false"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%-5level %date [%-5.5thread] %-40.40logger - %message%newline" /> </layout> </appender> <root> <appender-ref ref="RollingFileAppender" /> <level value="DEBUG" /> </root> </log4net> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <appSettings> <add key="StoragePath" value="MYDICOM/"/> <add key="Port" value="11112"/> <add key="CalledAE" value="STORESCP11112"/> </appSettings> </configuration>

 

posted @ 2022-04-12 09:46  xiaojianjian  阅读(825)  评论(0)    收藏  举报