------------------------------------------------------------------------------
| 584 | |
| 585 | //------------------------------------------------------------------------------ |
| 586 | int vtkSocket::Receive(void* data, int length, int readFully /*=1*/) |
| 587 | { |
| 588 | #ifndef VTK_SOCKET_FAKE_API |
| 589 | if (!this->GetConnected()) |
| 590 | { |
| 591 | vtkErrorMacro("Not connected."); |
| 592 | return 0; |
| 593 | } |
| 594 | |
| 595 | #if defined(_WIN32) && !defined(__CYGWIN__) |
| 596 | int tries = 0; |
| 597 | #endif |
| 598 | |
| 599 | char* buffer = reinterpret_cast<char*>(data); |
| 600 | int total = 0; |
| 601 | do |
| 602 | { |
| 603 | int nRecvd; |
| 604 | vtkRestartInterruptedSystemCallMacro( |
| 605 | recv(this->SocketDescriptor, buffer + total, length - total, 0), nRecvd); |
| 606 | |
| 607 | if (nRecvd == 0) |
| 608 | { |
| 609 | // peer shut down |
| 610 | return 0; |
| 611 | } |
| 612 | |
| 613 | #if defined(_WIN32) && !defined(__CYGWIN__) |
| 614 | if ((nRecvd == vtkSocketErrorReturnMacro)) |
| 615 | { |
| 616 | int lastError = WSAGetLastError(); |
| 617 | if (lastError == WSAECONNABORTED) |
| 618 | { |
| 619 | // From the receiver we cannot know if the connection abort is expected or not, this is why |
| 620 | // we output a trace instead of an error. |
| 621 | vtkLog(TRACE, "Socket error: connection abort."); |
| 622 | return 0; |
| 623 | } |
| 624 | else if (lastError == WSAENOBUFS) |
| 625 | { |
| 626 | // On long messages, Windows recv sometimes fails with WSAENOBUFS, but |
| 627 | // will work if you try again. |
| 628 | if ((tries++ < 1000)) |
| 629 | { |
| 630 | Sleep(1); |
| 631 | continue; |
| 632 | } |
| 633 | } |
| 634 | |
| 635 | vtkSocketErrorMacro(vtkErrnoMacro, "Socket error in call to recv."); |
| 636 | return 0; |
| 637 | } |
| 638 | #endif |
| 639 | |
| 640 | total += nRecvd; |
| 641 | } while (readFully && (total < length)); |
| 642 | |
| 643 | return total; |