实例介绍
【实例简介】dicom批量上传
【实例截图】
【核心代码】
#include "HDicomEnvironment.h"
#include <dcmtk/oflog/oflog.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmdata/dcpath.h>
#include <dcmtk/dcmnet/diutil.h>
#include <dcmtk/dcmnet/cond.h>
#include <dcmtk/dcmtls/tlslayer.h>
: m_pAssociation(Q_NULLPTR)
, m_pNetwork(Q_NULLPTR)
, m_pParameters(Q_NULLPTR)
, m_pDicomObserver(Q_NULLPTR)
, m_blockMode(DIMSE_NONBLOCKING)
, m_connectTimeoutSeconds(30)
, m_dimseTimeoutSeconds(10)
, m_acseTimeoutSeconds(30)
, m_peerPort(5678)
, m_maxReceivePDU(32768)
, m_peerHostName("localhost")
, m_peerAETitle("MGIUSDICOM")
, m_appAETitle("DebugTest")
, m_destAETitle("DebugTest")
{
}
{
this->DropNetwork();
}
{
m_pDicomObserver=pDicomObserver;
}
{
DicomPresentationContext presentationContext;
presentationContext.abstractSyntaxName = abstractSyntax;
OFListConstIterator(OFString) it = transferSyntaxes.begin();
OFListConstIterator(OFString) endOfList = transferSyntaxes.end();
while (it != endOfList)
{
presentationContext.transferSyntaxes.push_back(*it);
it ;
}
presentationContext.roleSelect = role;
m_presentationContexts.push_back(presentationContext);
}
{
m_presentationContexts.clear();
}
{
if (this->IsConnected())
{
return NET_EC_AlreadyConnected;
}
this->DropNetwork();
OFCondition condition= ASC_initializeNetwork(NET_REQUESTOR, 0, m_acseTimeoutSeconds, &m_pNetwork);
if (condition.bad())
{
DCMNET_ERROR(DimseCondition::dump(tempStr, condition));
return condition;
}
if (condition.bad())
{
DCMNET_ERROR(DimseCondition::dump(tempStr, condition));
return condition;
}
if (condition.bad())
{
DCMNET_ERROR(DimseCondition::dump(tempStr, condition));
return condition;
}
const OFString tempLocalHost = OFStandard::getHostName();
sprintf(tempPeerHost, "%s:%d", m_peerHostName.c_str(), OFstatic_cast(int, m_peerPort));
condition = ASC_setPresentationAddresses(m_pParameters, tempLocalHost.c_str(), tempPeerHost);
if (condition.bad())
{
DCMNET_ERROR(DimseCondition::dump(tempStr, condition));
return condition;
}
Uint32 numContexts = ASC_countPresentationContexts(m_pParameters);
if (numContexts <= 127)
{
nextFreePresID = 2 * numContexts 1; /* add 1 to point to the next free ID*/
}
if ((numContexts m_presentationContexts.size()) > 128)
{
DCMNET_WARN("Number of presentation contexts exceeds 128 (" << numContexts m_presentationContexts.size()
<< "). Some contexts will not be negotiated");
}
else
{
DCMNET_TRACE("Configured " << numContexts << " presentation contexts from config file");
if (m_presentationContexts.size() > 0)
{
DCMNET_TRACE("Adding another " << m_presentationContexts.size() << " presentation contexts configured for SCU");
}
}
OFListConstIterator(DicomPresentationContext) endOfContList = m_presentationContexts.end();
while ((contIt != endOfContList) && (nextFreePresID <= 255))
{
const Uint16 numTransferSyntaxes = OFstatic_cast(Uint16, (*contIt).transferSyntaxes.size());
const char** transferSyntaxes = new const char*[numTransferSyntaxes];
OFListIterator(OFString) endOfSyntaxList = (*contIt).transferSyntaxes.end();
while (syntaxIt != endOfSyntaxList)
{
transferSyntaxes[sNum] = (*syntaxIt).c_str();
syntaxIt;
sNum;
}
(*contIt).abstractSyntaxName.c_str(), transferSyntaxes,
numTransferSyntaxes,(*contIt).roleSelect);
transferSyntaxes = NULL;
if (condition.good())
{
contIt ;
nextFreePresID = 2;
}
else
{
DCMNET_ERROR("SetTransportLayerType Failed: " << DimseCondition::dump(tempStr, condition));
return condition;
}
}
if (numContexts == 0)
{
DCMNET_ERROR("Cannot initialize network: No presentation contexts defined");
}
DCMNET_DEBUG("Configured a total of " << numContexts << " presentation contexts for SCU");
return condition;
}
{
OFCondition condition;
{
DCMNET_DEBUG("Cleaning up internal association and network structures");
}
if (m_pParameters)
{
ASC_destroyAssociationParameters(&m_pParameters); // 内部返回 EC_Normal 并将 parameters 置空
m_pParameters = NULL;
if (m_pAssociation)
{
m_pAssociation->params = NULL;
}
}
condition = ASC_destroyAssociation(&m_pAssociation);
if (condition.bad()) return condition;
condition = ASC_dropNetwork(&m_pNetwork);
}
{
OFString errorString;
DcmTransportLayerStatus tlsStatus = TCS_ok;
DcmTLSTransportLayer *pTlsTransport = new DcmTLSTransportLayer(DICOM_APPLICATION_REQUESTOR, NULL, false); // 不需要自己管理 DcmTLSTransportLayer 资源释放
tlsStatus = pTlsTransport->setPrivateKeyFile(HDicomEnvironment::GetPrivateKeyFile().toStdString().c_str(), SSL_FILETYPE_PEM);
if (tlsStatus != TCS_ok)
{
DCMNET_ERROR("DicomSCUBase::UseSecureConnection() set private key failed!");
return makeDcmnetCondition(DULC_TLSERROR, OF_error, "set private key failed.");
}
tlsStatus = pTlsTransport->setCertificateFile(HDicomEnvironment::GetCertificateFile().toStdString().c_str(), SSL_FILETYPE_PEM);
if (tlsStatus != TCS_ok)
{
DCMNET_ERROR("DicomSCUBase::UseSecureConnection() set certificate failed!");
return makeDcmnetCondition(DULC_TLSERROR, OF_error, "set certificate failed.");
}
if (!pTlsTransport->checkPrivateKeyMatchesCertificate())
{
DCMNET_ERROR("DicomSCUBase::UseSecureConnection() check private key match certificate failed!");
return makeDcmnetCondition(DULC_TLSERROR, OF_error, "check private key match certificate failed.");
}
foreach (QString trustedCert, trustedCerts)
{
tlsStatus = pTlsTransport->addTrustedCertificateFile(trustedCert.toStdString().c_str(), SSL_FILETYPE_PEM);
if (tlsStatus != TCS_ok)
{
DCMNET_WARN("Add trusted certificate failed: " << trustedCert.toStdString().c_str());
}
}
pTlsTransport->setCertificateVerification(DCV_requireCertificate);
if (condition.good())
{
condition = ASC_setTransportLayerType(m_pParameters, OFTrue);
if (condition.bad())
{
DCMNET_ERROR("SetTransportLayerType Failed: " << DimseCondition::dump(errorString, condition));
}
}
else
{
DCMNET_ERROR("SetTransportLayer Failed: " << DimseCondition::dump(errorString, condition));
}
return condition;
}
{
if (this->IsConnected()) return NET_EC_AlreadyConnected;
//DCMNET_INFO("Request Parameters:" << OFendl << ASC_dumpParameters(tempStr, m_pParameters, ASC_ASSOC_RQ));
DCMNET_INFO("Requesting Association");
OFCondition condition = ASC_requestAssociation(m_pNetwork, m_pParameters, &m_pAssociation);
if (condition.bad())
{
if (condition == DUL_ASSOCIATIONREJECTED)
{
T_ASC_RejectParameters rej;
ASC_getRejectParameters(m_pParameters, &rej);
DCMNET_ERROR("Association Rejected:" << OFendl << ASC_printRejectParameters(tempStr, &rej));
return condition;
}
else
{
DCMNET_ERROR("Association Request Failed: " << DimseCondition::dump(tempStr, condition));
return condition;
}
}
if (ASC_countAcceptedPresentationContexts(m_pParameters) == 0)
{
DCMNET_ERROR("No Acceptable Presentation Contexts");
return NET_EC_NoAcceptablePresentationContexts;
}
DCMNET_INFO("Association Accepted (Max Send PDV: " << OFstatic_cast(unsigned long, m_pAssociation->sendPDVLength) << ")");
}
{
OFString errorString;
OFCondition condition;
DCMNET_INFO("Releasing Association");
condition = ASC_releaseAssociation(m_pAssociation);
if (condition.bad())
{
DCMNET_ERROR("Association Release Failed: " << DimseCondition::dump(errorString, condition));
}
return condition;
}
{
OFString errorString;
OFCondition condition;
condition = ASC_abortAssociation(m_pAssociation);
if (condition.bad())
{
DCMNET_ERROR("Association Abort Failed: " << DimseCondition::dump(errorString, condition));
}
return condition;
}
{
OFBool retValue = OFFalse;
if (m_pAssociation!=NULL && m_pAssociation->DULassociation!=NULL)
{
retValue = OFTrue;
}
return retValue;
}
{
DIC_US msgId = m_pAssociation->nextMsgID ;
DIC_US status;
DcmDataset *statusDetail = NULL;
OFCondition condition = DIMSE_echoUser(m_pAssociation, msgId, m_blockMode, m_dimseTimeoutSeconds, &status, &statusDetail);
if (condition.good())
{
DCMNET_INFO("Received Echo Response (" << DU_cechoStatusString(status) << ")");
}
else
{
OFString temp_str;
DCMNET_ERROR("Echo Failed: " << DimseCondition::dump(temp_str, condition));
}
{
DCMNET_DEBUG("Status Detail (should never be any):" << OFendl << DcmObject::PrintHelper(*statusDetail));
delete statusDetail;
}
}
T_DIMSE_C_FindRQ *pRequest, T_DIMSE_C_FindRSP *pRsponse,
DIMSE_FindUserCallback callback, void *callbackData)
{
T_ASC_PresentationContextID presId;
DcmFileFormat dcmFileFormat;
OFString tempString;
OFCondition condition;
OFListConstIterator(OFString) lastKey = pOverrideKeys->end();
DcmDataset* requestIdentifiers = dcmFileFormat.getDataset();
DcmPathProcessor dcmPathProcessor;
dcmPathProcessor.setItemWildcardSupport(OFFalse);
dcmPathProcessor.checkPrivateReservations(OFFalse);
while (keyPath != lastKey)
{
condition = dcmPathProcessor.applyPathWithValue(requestIdentifiers, *keyPath);
if (condition.bad())
{
DCMNET_ERROR("Bad override key/path: " << *keyPath << ": " << condition.text());
return condition;
}
keyPath ;
}
if (presId == 0)
{
DCMNET_ERROR("No presentation context");
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
}
pRequest->DataSetType = DIMSE_DATASET_PRESENT;
pRequest->Priority = DIMSE_PRIORITY_MEDIUM;
pRequest->MessageID = m_pAssociation->nextMsgID ;
DCMNET_INFO("Sending Find Request (MsgID " << pRequest->MessageID << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pRequest, DIMSE_OUTGOING, NULL, presId));
DCMNET_INFO("Request Identifiers:" << OFendl << DcmObject::PrintHelper(*requestIdentifiers));
// TODO 回调处理
condition = DIMSE_findUser(m_pAssociation, presId, pRequest, requestIdentifiers, callback, callbackData,
m_blockMode, m_dimseTimeoutSeconds,
pRsponse, &statusDetail);
if (condition.good())
{
DCMNET_INFO("Received Final Find Response (" << DU_cfindStatusString(pRsponse->DimseStatus) << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pRsponse, DIMSE_INCOMING));
}
else
{
DCMNET_ERROR("Find Failed, query keys:");
DCMNET_ERROR(DcmObject::PrintHelper(dcmFileFormat));
DCMNET_ERROR(DimseCondition::dump(tempString, condition));
}
{
DCMNET_DEBUG("Status Detail:" << OFendl << DcmObject::PrintHelper(*statusDetail));
delete statusDetail;
}
}
T_DIMSE_C_GetRQ *pRequest, T_DIMSE_C_GetRSP *pRsponse,
DIMSE_GetUserCallbackEx callback, void *callbackData,
DIMSE_SubOpProviderCallbackEx subOpCallback, void *subOpCallbackData)
{
T_ASC_PresentationContextID presentationId;
DcmFileFormat dcmFileFormat;
OFString tempString;
OFCondition condition;
DcmPathProcessor dcmPathProcessor;
dcmPathProcessor.setItemWildcardSupport(OFFalse);
dcmPathProcessor.checkPrivateReservations(OFFalse);
OFListConstIterator(OFString) lastKey = pOverrideKeys->end();
while (keyPath != lastKey)
{
condition = dcmPathProcessor.applyPathWithValue(requestIdentifiers, *keyPath);
if (condition.bad())
{
DCMNET_ERROR("Bad override key/path: " << *keyPath << ": " << condition.text());
return condition;
}
keyPath ;
}
if (presentationId == 0)
{
DCMNET_ERROR("No presentation context");
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
}
pRequest->DataSetType = DIMSE_DATASET_PRESENT;
pRequest->Priority = DIMSE_PRIORITY_MEDIUM;
pRequest->MessageID = m_pAssociation->nextMsgID ;
DCMNET_INFO("Sending Find Request (MsgID " << pRequest->MessageID << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pRequest, DIMSE_OUTGOING, NULL, presentationId));
DCMNET_INFO("Request Identifiers:" << OFendl << DcmObject::PrintHelper(*requestIdentifiers));
DcmDataset *responseIdentifiers = NULL;
if (condition.good())
{
condition = DIMSE_getUserEx(m_pAssociation, presentationId, pRequest, requestIdentifiers, callback, callbackData,
m_blockMode, m_dimseTimeoutSeconds,
m_pNetwork, subOpCallback, subOpCallbackData,
pRsponse, &statusDetail, &responseIdentifiers);
}
if (condition.good())
{
DCMNET_INFO("Received Final Get Response (" << DU_cfindStatusString(pRsponse->DimseStatus) << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pRsponse, DIMSE_INCOMING));
}
else
{
DCMNET_ERROR("Get Failed, query keys:");
DCMNET_ERROR(DcmObject::PrintHelper(dcmFileFormat));
DCMNET_ERROR(DimseCondition::dump(tempString, condition));
}
{
DCMNET_DEBUG("Status Detail:" << OFendl << DcmObject::PrintHelper(*statusDetail));
delete statusDetail;
}
if (responseIdentifiers != NULL)
{
DCMNET_DEBUG("Status Detail:" << OFendl << DcmObject::PrintHelper(*responseIdentifiers));
delete responseIdentifiers;
}
}
T_DIMSE_C_MoveRQ *pRequest, T_DIMSE_C_MoveRSP *pResponse,
DIMSE_MoveUserCallback callback, void *callbackData,
DIMSE_SubOpProviderCallback subOpCallback, void *subOpCallbackData)
{
T_ASC_PresentationContextID presentationID = 0;
DcmFileFormat dcmFileFormat;
DcmDataset *pResponseIdentifiers = NULL;
DcmDataset *pStatusDetail = NULL;
OFString tempString;
OFCondition condition = EC_Normal;
DcmPathProcessor dcmPathProcessor;
dcmPathProcessor.setItemWildcardSupport(OFFalse);
dcmPathProcessor.checkPrivateReservations(OFFalse);
OFListConstIterator(OFString) lastKey = pOverrideKeys->end();
while (keyPath != lastKey)
{
condition = dcmPathProcessor.applyPathWithValue(requestIdentifiers, *keyPath);
if (condition.bad())
{
DCMNET_ERROR("Bad override key/path: " << *keyPath << ": " << condition.text());
return condition;
}
keyPath ;
}
if (presentationID == 0)
{
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
}
pRequest->MessageID = m_pAssociation->nextMsgID ;
strcpy(pRequest->AffectedSOPClassUID, abstractSyntax);
strcpy(pRequest->MoveDestination, m_destAETitle.c_str());
pRequest->Priority = DIMSE_PRIORITY_MEDIUM;
pRequest->DataSetType = DIMSE_DATASET_PRESENT;
DCMNET_DEBUG("Sending Move Request (MsgID " << pRequest->MessageID << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pRequest, DIMSE_OUTGOING, NULL, presentationID));
{
condition = DIMSE_moveUser(m_pAssociation, presentationID, pRequest, requestIdentifiers,
callback, callbackData, m_blockMode, m_dimseTimeoutSeconds, m_pNetwork,
subOpCallback, subOpCallbackData,
pResponse, &pStatusDetail, &pResponseIdentifiers);
}
{
DCMNET_INFO("Received Final Move Response (" << DU_cmoveStatusString(pResponse->DimseStatus) << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pResponse, DIMSE_INCOMING));
if (pResponseIdentifiers != NULL)
{
DCMNET_DEBUG("Response Identifiers:" << OFendl << DcmObject::PrintHelper(*pResponseIdentifiers));
}
}
else
{
DCMNET_ERROR("Move Request Failed: " << DimseCondition::dump(tempString, condition));
}
if (pStatusDetail != NULL)
{
DCMNET_DEBUG("Status Detail:" << OFendl << DcmObject::PrintHelper(*pStatusDetail));
delete pStatusDetail;
}
{
delete pResponseIdentifiers;
}
}
T_DIMSE_C_StoreRQ *pRequest, T_DIMSE_C_StoreRSP *pResponse,
DIMSE_StoreUserCallback callback, void *callbackData)
{
OFString tempString;
OFCondition condition = EC_Normal;
DIC_UI sopClass;
DIC_UI sopInstance;
DcmDataset *pStatusDetail = NULL;
T_ASC_PresentationContextID presentationID;
{
DCMNET_ERROR("No SOP Class or Instance UID in store dataset");
condition = DIMSE_BADDATA;
}
if (datasetXfer.getXfer() != EXS_Unknown)
{
presentationID = ASC_findAcceptedPresentationContextID(m_pAssociation, sopClass, datasetXfer.getXferID());
}
else
{
presentationID = ASC_findAcceptedPresentationContextID(m_pAssociation, sopClass);
}
if (presentationID == 0)
{
DCMNET_ERROR("No presentation context");
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
}
strcpy(pRequest->AffectedSOPClassUID, sopClass);
strcpy(pRequest->AffectedSOPInstanceUID, sopInstance);
pRequest->DataSetType = DIMSE_DATASET_PRESENT;
pRequest->Priority = DIMSE_PRIORITY_MEDIUM;
pRequest->MessageID = m_pAssociation->nextMsgID ;
DCMNET_INFO("Sending C-STORE Request (MsgID " << pRequest->MessageID << ")");
{
condition = DIMSE_storeUser(m_pAssociation, presentationID, pRequest, NULL, pStoreDataset,
callback, callbackData,
m_blockMode, m_dimseTimeoutSeconds, pResponse, &pStatusDetail);
}
{
DCMNET_INFO("Received Store Response (" << DU_cstoreStatusString(pResponse->DimseStatus) << ")");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, *pResponse, DIMSE_INCOMING, NULL, presentationID));
}
else
{
DCMNET_ERROR("Store Failed:" << OFendl << DimseCondition::dump(tempString, condition));
}
{
DCMNET_DEBUG("Status Detail:" << OFendl << DcmObject::PrintHelper(*pStatusDetail));
delete pStatusDetail;
}
}
DcmDataset *pRequestIdentifiers, DIMSE_GetUserCallbackEx callback, void *callbackData,
T_DIMSE_BlockingMode blockMode, int timeout, T_ASC_Network *pNetwork,
DIMSE_SubOpProviderCallbackEx subOpCallback, void *pSubOpCallbackData,
T_DIMSE_C_GetRSP *pResponse, DcmDataset **ppStatusDetail, DcmDataset **ppResponseIdentifers)
{
OFCondition condition;
OFString tempString;
DIC_US msgId;
OFBool continueSession = OFTrue;
T_DIMSE_Message requestMSG, responseMSG;
bzero((char*)&responseMSG, sizeof(responseMSG));
pRequest->DataSetType = DIMSE_DATASET_PRESENT;
requestMSG.msg.CGetRQ = *pRequest;
if (condition.bad())
{
DCMNET_ERROR("Failed sending C-GET request: " << DimseCondition::dump(tempString, condition));
return condition;
}
{
T_ASC_PresentationContextID recvPresentationID = 0;
if (condition.bad())
{
DCMNET_ERROR("Failed receiving C-GET receiving DIMSE command" << DimseCondition::dump(tempString, condition));
return condition;
}
{
responseCount;
*pResponse = responseMSG.msg.CGetRSP;
DCMNET_INFO("Received C-GET Response");
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, responseMSG, DIMSE_INCOMING, NULL, recvPresentationID));
if (callback != NULL)
{
callback(callbackData, pRequest, responseCount, pResponse, continueSession);
}
}
else if (responseMSG.CommandField == DIMSE_C_STORE_RQ) // C-STORE 存储请求
{
T_DIMSE_C_StoreRQ cstoreRequest = responseMSG.msg.CStoreRQ;
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, responseMSG, DIMSE_INCOMING, NULL, recvPresentationID));
DcmDataset *pResponseDataSet = NULL;
condition = DIMSE_receiveDataSetInMemory(m_pAssociation, m_blockMode, m_dimseTimeoutSeconds, &recvPresentationID, &pResponseDataSet, NULL, NULL);
if (condition.bad())
{
DCMNET_ERROR("Failed receiving C-GET receiving DIMSE command" << DimseCondition::dump(tempString, condition));
cstoreReturnStatus = STATUS_STORE_Error_CannotUnderstand;
continueSession = OFFalse;
}
else
{
if (subOpCallback)
{
subOpCallback(pSubOpCallbackData, &cstoreRequest, &recvPresentationID, continueSession, cstoreReturnStatus, pResponseDataSet);
}
}
bzero((char*)&cstoreResponseMSG, sizeof(cstoreResponseMSG));
cstoreResponseMSG.CommandField = DIMSE_C_STORE_RSP;
T_DIMSE_C_StoreRSP &storeRsp = cstoreResponseMSG.msg.CStoreRSP;
storeRsp.MessageIDBeingRespondedTo = cstoreRequest.MessageID;
storeRsp.DimseStatus = cstoreReturnStatus;
storeRsp.DataSetType = DIMSE_DATASET_NULL;
OFStandard::strlcpy(storeRsp.AffectedSOPInstanceUID, cstoreRequest.AffectedSOPInstanceUID, sizeof(storeRsp.AffectedSOPInstanceUID));
storeRsp.opts = O_STORE_AFFECTEDSOPCLASSUID | O_STORE_AFFECTEDSOPINSTANCEUID;
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, cstoreResponseMSG, DIMSE_OUTGOING, NULL, presentationID));
if (condition.bad())
{
DCMNET_ERROR("Failed sending C-STORE response: " << DimseCondition::dump(tempString, condition));
}
}
else
{
DCMNET_ERROR("Expected C-GET response or C-STORE request but received DIMSE command 0x"
<< std::hex << std::setfill('0') << std::setw(4)
<< OFstatic_cast(unsigned int, responseMSG.CommandField));
DCMNET_DEBUG(DIMSE_dumpMessage(tempString, responseMSG, DIMSE_INCOMING, NULL, presentationID));
condition = DIMSE_BADCOMMANDTYPE;
continueSession = OFFalse;
}
}
}
标签: DICOM
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论