此程序引用的是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>

DICOM-SCP,可以直接使用的SCP(.net framework 4.5)控制台接收端的更多相关文章

  1. scp命令报错-bash: scp: command not found

    # scp -bash: scp: command not found # which scp /usr/bin/scp # rpm -qf /usr/bin/scp openssh-clients- ...

  2. dicom 影像通信(scu、scp)的c-echo、c-store、c-find、c-move

    本文主要描述,dicom通信的scu,scp的c-echo.c-store.c-find.c-move的使用. DicomServiceIDicomServiceProviderIDicomCStor ...

  3. scp 基本用法(提高scp传输速度)

    Outline spc 可以帮你实现: Linux Server 之间互传数据: Linux Server 和 Windows Server 之间互传数据: 参考: https://www.cnblo ...

  4. scp报错 -bash: scp: command not found

    环境:RHEL6.5 使用scp命令报错: [root@oradb23 media]# scp /etc/hosts oradb24:/etc/ -bash: scp: command not fou ...

  5. linux之cp/scp命令+scp命令详解

    名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数 ...

  6. Linux学习之三--scp命令

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  7. scp 上传文件到多个服务器节点

    参考:scp批量上传文件到多台机器上(升级版) 实测,代码可运行. 1.如果遇到syntax error near unexpected token问题,基本是由于windows环境下编写的shell ...

  8. scp命令详解

    \ svn 删除所有的 .svn文件 find . -name .svn -type d -exec rm -fr {} \; linux之cp/scp命令+scp命令详解   名称:cp 使用权限: ...

  9. linux命令-cp/scp {拷贝}

    一 命令解释 名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 命令参数: -a 尽可能 ...

  10. scp详解

    scp 命令 ================== scp 可以在 2个 linux 主机间复制文件: 命令基本格式:        scp [可选参数] file_source file_targe ...

随机推荐

  1. git常见问题Q&A

    git基本命令解释 git restore --staged .:移除暂存区文件,不影响本地(撤销git add . 操作) git add -u:将删除文件的操作同步到暂存区.将本地的删除同步到版本 ...

  2. JAVA 传输post传输长字符、数据编码解码 反序列化字符串

    JAVA 传输post传输长字符.数据编码解码 1.前段传输 这是传输的数组对象 2.后端接收格式已解码 JS代码: $.ajax({ url:prefix+"/importModelTre ...

  3. php 5.4 var_export的改进

    用 var_export 来将数据存储到 php 配置文件里的时候,发现var_export转出来的变量定义还是 array()这种形式,不能转为[],所以自己写个函数来转换一下,代码如下: < ...

  4. Transformers包使用记录

    Transformers是著名的深度学习预训练模型集成库,包含NLP模型最多,CV等其他领域也有,支持预训练模型的快速使用和魔改,并且模型可以快速在不同的深度学习框架间(Pytorch/Tensorf ...

  5. golang之copier

    今天我们要介绍的copier库就能处理不同类型之间的赋值.除此之外,copier还能: 调用同名方法为字段赋值: 以源对象字段为参数调用目标对象的方法,从而为目标对象赋值(当然也可以做其它的任何事情) ...

  6. 性能检测工具之Lighthouse

    转载:https://mp.weixin.qq.com/s?src=11&timestamp=1618929340&ver=3020&signature=oXyx*RDLXjN ...

  7. git针对指定网站设置代理

    我们经常要用到各种git地址,比如github.gitee还有自己搭建的git等等. 但是github我们经常拉取和推送代码的时候超时,这时候如果我们搜索会发现大量的文章都是告诉我们设置全局系统代理: ...

  8. Android运行时请求权限封装

    @ 目录 1 介绍 2 测试用例设计 3 实现 4 用例测试 5 总结 本文目的:"借助透明Activity封装一个易于调用的权限请求模块" 1 介绍 Android权限的校验和申 ...

  9. ClickHouse 物化视图学习总结

    物化视图 物化视图源表--基础数据源 创建源表,因为我们的目标涉及报告聚合数据而不是单条记录,所以我们可以解析它,将信息传递给物化视图,并丢弃实际传入的数据.这符合我们的目标并节省了存储空间,因此我们 ...

  10. 《Django 5 By Example》阅读笔记:p521-p542

    <Django 5 By Example>学习第 18 天,p521-p542 总结,总计 22 页. 一.技术总结 1.django-parler django-parler 用于 mo ...