views:

314

answers:

3

Why I always get WSAETIMEDOUT error in this code :

var fUDPBuf: array [1..UdpPacketSize] of byte;
{...}
UDPSocket := TUDPBlockSocket.Create;
UDPSocket.Bind(UDPIP, UDPPort);
if UDPSocket.LastError = 0 then
  Raise EDevFail.Create(Format(SPortFailed, [UDPPort]));

while not Terminated do begin
  BytesRead := UDPSocket.RecvBufferEx(@fUDPBuf[1], UdpPacketSize, 1000);
  if BytesRead <= 0 then
    case UDPSocket.LastError of
      0, WSAETIMEDOUT: Continue;
      WSAECONNRESET, WSAENETRESET,
      WSAENOTCONN, WSAECONNABORTED,
      WSAENETDOWN: begin
                     Raise EDevFail.Create(UDPSocket.GetErrorDesc(UDPSocket.LastError));
                     UDPSocket.CloseSocket;
                   end;
      else begin
        Raise EDevFail.Create(UDPSocket.GetErrorDesc(UDPSocket.LastError));
        UDPSocket.CloseSocket;
      end;
    end;

  //Sleep(1);
  ProcessData(@fUDPBuf[1]);
  inc(PacketCount);
end;

I'm sure that I receive UDP data from e network device as much as UdpPacketSize.

+1  A: 

In the call "UDPSocket.RecvBufferEx(@fUDPBuf[1], UdpPacketSize, 1000);" I would presume that the last number is the timeout period. This is done so that it doesn't sit waiting forever, but rather checks periodically if the thread has been Terminated using the while loop condition. So the timeout is a normal situation for this sort of code, and can be ignored.

mj2008
anyway my codes in "while not Terminated" loop. And I'm sure I received 1305 bytes in every 5 milliseconds.
SimaWB
"anyway my codes in "while not Terminated" loop." - yes, that's the test to see if it has been terminated. The Not is naturally there. As for the timing, it is possible that the socket notification of data hasn't come in due to the system being busy, and this wait times out.
mj2008
A: 

I found that. The error is in

if UDPSocket.LastError = 0 then

LastError is 10049=Can't assign requested address at this point. So why I couldn't Bind the UDPIP address. I've check the IP and Port. These are correct. And there is no other software listening this port.

SimaWB
A: 

I solved my problem :)

UDPSocket.Bind(UDPIP, UDPPort);

must be

UDPSocket.Bind('0.0.0.0', UDPPort);

And

if UDPSocket.LastError = 0 then

must be

if UDPSocket.LastError <> 0 then

For to check IP address where data come from

if UDPSocket.GetRemoteSinIP<>UDPIP then ....
SimaWB