此程序引用的是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. 22.使用Rancher2.0搭建Kubernetes集群

    使用Rancher2.0搭建Kubernetes集群 中文文档:https://docs.rancher.cn/docs/rancher2 安装Rancher2.0 使用下面命令,我们快速的安装 # ...

  2. 20.Kubernetes可视化界面kubesphere

    Kubernetes可视化界面kubesphere 前言 Kubernetes也提供了默认的dashboard页面,但是功能不是很强大,这里就不使用了 而是采用Kubesphere大桶全部的devop ...

  3. CAD Plus 移动端使用帮助

    Mac端使用帮助 English help 如果您有疑问或需要帮助请发送邮件至 3167292926@qq.com 1. 权限要求 1.1 获取位置信息 使用文件管理功能时显示网络信息需要获取位置信息 ...

  4. 异常断链的惨痛经历!拯救Air780EP模块紧急项目

    ​ 必须要吐槽一下:最近被老板驱使,要用Air780EP模块做几个紧急项目... 就怕紧急项目,时间紧任务重,遇到了一些棘手问题,可把我给折腾死了-- 这里把遇到的问题,排查记录下来,看能不能帮到因遇 ...

  5. macos安装Charles

    一.安装jdk 1.地址:https://www.oracle.com/cn/java/technologies/downloads/#java11,下载后双击安装 2.查看java的安装地址,在ma ...

  6. 敏捷开发:Scrum 中的 Product Backlog 介绍

    Product Backlog 产品待办列表 在计划开发产品功能时,都希望产品功能上线后,用户能够喜欢并经常使用. 因此在开发产品新功能时,就要衡量哪些产品需求是对用户最有价值,这是最应该思考的问题. ...

  7. 方法区回收过程与GC的并发与并行

    主要回收废弃常量和无用的类 废弃常量包括字面量.类或接口.方法.字段的符号引用等 废弃指的是没有任何地方引用这个常量. 无用的类 满足的三个条件: 1.没有该类的任何实例存在 2.加载该类的Class ...

  8. 1分钟学会如何提升PCIe通信速率,基于RK3568J + FPGA国产平台!

    测试数据汇总 表 1 PCIe总线介绍 PCIe,即PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准.主要用 ...

  9. 攻防世界:Crypto习题之easy_RSA

    攻防世界:Crypto习题之easy_RSA RSA 加密 在非对称加密算法中,单向函数被广泛应用,用于确保从公钥加密后的密文无法轻易推导出私钥,从而保证数据的安全性.而其中最著名的算法便是 RSA ...

  10. uniapp权限判断

    写法如下 // 检查是否有写入外部存储的权限 function writeExternalStoragePermission() { return new Promise((resolve, reje ...