Bug #1006
closeddefragmentTCP() does not handle WSAEWOULDBLOCK error on Windows when no data ready from non-blocking socket for read()
100%
Description
The following forum posting from "wrenashe" reports a possible bug and corresponding solution:
We (Bonnie found the issue) have a DICOM message relay on Windows to test,
storescu --> our DICOM router(SCP --> SCU, using DCMTK3.6.6) --> external SCP,We got the error shown below on Windows, We do not have the same problem on Linux with our DICOM router built from the same DCMTK.
C:\testbin>storescuaec xxxPACS4 -aet CL_SCP LOCALHOST 11110 C:\testbin\data\*.1-------.12.0:
E: Store Failed, file: C:\testbin\data\CT.1.3.6.1.4.1.----------------------
E: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (An established connection was aborted by the software in your host machine.) occurred in routine: writeDataPDU
E: Store SCU Failed: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (An established connection was aborted by the software in your host machine.) occurred in routine: writeDataPDU
E: Association Abort Failed: 0006:031d TCP I/O Error (An established connection was aborted by the software in your host machine.) occurred in routine: sendAbortTCPThe investigation shows the DICOM router SCP side got an issue about "DIMSE Read PDV failed". In defragmentTCP(), read() in non-blocking mode fails when the socket is not ready to be read. The code is not aware of the situation like bytesRead = -1 and WSAEWOULDBLOCK as > the error, just returns DUL_NETWORKCLOSED and results in the failure.
The modified code diff (also from Bonnie here) fixes this problem on Windows against our testing scenario, just for your reference here, hope it helps.
3699a3700,3704 > #ifdef HAVE_WINSOCK_H > if (OFStandard::getLastNetworkErrorCode().value() == WSAEWOULDBLOCK) { > Sleep(1); > } > #endif 3713c3718,3722 < } while (bytesRead == -1 && OFStandard::getLastNetworkErrorCode().value() == DCMNET_EINTR); --- > } while ((bytesRead == -1 && OFStandard::getLastNetworkErrorCode().value() == DCMNET_EINTR) > #ifdef HAVE_WINSOCK_H > || (bytesRead == -1 && (OFStandard::getLastNetworkErrorCode().value() == WSAEWOULDBLOCK)) > #endif > ); 3723a3733,3743 > #ifdef HAVE_WINSOCK_H > DWORD errorCode = GetLastError(); > LPVOID lpMsgBuf; > FormatMessage( > FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, > NULL, errorCode, > MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), > (LPTSTR)&lpMsgBuf, 0, NULL); > printf("defragmentTCP(): bytesRead=%d errorCode=%d %s\n", bytesRead, errorCode, (LPTSTR)lpMsgBuf); > LocalFree(lpMsgBuf); > #endif
Updated by Marco Eichelberg over 3 years ago
- Status changed from New to Closed
- Assignee set to Marco Eichelberg
- % Done changed from 0 to 100
- Estimated time set to 2:00 h
Closed by commit #038487699.