Skip to content

gonetdicom

ReleaseCIGoDoc

gonetdicom implements the DICOM networking protocol and the DICOMweb (PS3.18) transactions. Where godicom is about the bytes of a dataset, gonetdicom is about moving them between machines.

bash
go get github.com/godicom-dev/gonetdicom@latest
gonetdicom
 └── github.com/godicom-dev/godicom

Datasets and pixel I/O come from godicom; gonetdicom owns Upper Layer PDUs, DIMSE command sets, association negotiation, and HTTP DICOMweb. DIMSE behaviour is aligned with pynetdicom, using its fixtures as a git submodule; DICOMweb follows PS3.18.

Packages

PackageRole
aeApplication Entity — association as SCU or SCP, TLS, role selection, user identity
dimseDIMSE command sets, C- and N- services
pduUpper Layer PDUs and PDV fragmentation
dicomwebWADO-RS / STOW-RS / QIDO-RS client, plus an origin-server MVP
statusNamed DIMSE status constants

Almost everything you write day to day lives in ae.

The two shapes

As an SCU — you initiate. ae.Dial negotiates an association and returns an *ae.Association you send DIMSE messages on:

go
assoc, err := ae.Dial(ctx, ae.Config{AETitle: "MYSCU"}, "pacs.example:11112", "ANY-SCP")
if err != nil {
	log.Fatal(err)
}
defer assoc.Abort()

if err := assoc.CEcho(ctx); err != nil {
	log.Fatal(err)
}
if err := assoc.Release(ctx); err != nil {
	log.Fatal(err)
}

As an SCP — you accept. ae.Serve blocks on a listener, dispatching to the handlers you configured:

go
err := ae.Serve(ctx, ln, ae.ServerConfig{
	AETitle:                  "STORESCP",
	AcceptedAbstractSyntaxes: ae.AllStorageSOPClasses,
	OnCStore:                 handleStore,
})

Services

ServiceSCU methodSCP handler
C-ECHOCEchobuilt in
C-STORECStoreOnCStore
C-FINDCFindOnCFind
C-MOVECMoveOnCMove
C-GETCGetOnCGet
C-CANCELCCancel
N-EVENT-REPORTNEventReportOnNEventReport
N-GETNGetOnNGet
N-SETNSetOnNSet
N-ACTIONNActionOnNAction
N-CREATENCreateOnNCreate
N-DELETENDeleteOnNDelete

On this site

  • SCU — sending — verification, storage, query/retrieve, DIMSE-N, TLS, user identity
  • SCP — serving — storage, query, move destinations, identity negotiation
  • DICOMweb — the client, and the origin-server MVP

Logging

Silent by default, like leaving pynetdicom's debug_logger unset. A Config/Client logger wins over a context logger:

go
assoc, err := ae.Dial(ctx, ae.Config{AETitle: "MYSCU", Logger: logger}, addr, "ANY-SCP")

ctx = gonetdicom.WithLogger(ctx, logger) // shared with godicom.ReadFileContext etc.

At LevelDebug the AE logs PDU send/recv and DIMSE command summaries, with fixed attribute keys: component, calling_ae, called_ae, pdu_type_name, command_name, pc_id, message_id, status.

Testing against a real PACS

An optional soak test, skipped unless the environment names a PACS:

bash
GONETDICOM_PACS_ADDR=host:11112 GONETDICOM_PACS_AE=ANY-SCP \
  go test -tags=integration ./ae -run TestIntegrationCEchoPACS -v

Repository documents

Released under the MIT License.