Clément 148 Posted November 11 Hi, I'm using 12.1 with ICS 8.69. This code is driving me nuts. procedure TDiscoverClient.event_ServerReply(aSender: TObject; ErrCode: Word); const _BufferSize = 1024; begin if errCode = 0 then begin var lBuffer : Tbytes ; var lFromSock : TSockAddr; var lFromLen : Integer; var lCount : Integer; SetLength( lBuffer, _BufferSize ); lcount := fSender.ReceiveFrom(@lBuffer[0], _BufferSize, lFromSock, lFromLen ); if lCount>0 then begin if Assigned( fOnHostFound ) or Assigned(fOnHostAlive) then begin var lRespParts := SplitString( TEncoding.ANSI.GetString( lBuffer,0,lCount ),':'); var lServerMachineName := ''; var lServerMachineIP : String := String(inet_ntoa(lFromSock.sin_addr)); if lRespParts[0] = 'M' then lServerMachineName := lRespParts[1]; if Assigned(fOnHostFound) then fOnHostFound(Self, lServerMachineIP,lServerMachineName ); if Assigned(fOnHostAlive) then fOnHostAlive(Self, lServerMachineIP,lServerMachineName ); end; end else fErrMsg := Ics_WSAGetLastError; end; end; The code is executed from a child form, from my main VCL application. I need to check if a UDP server is alive ( or found). Anyway, I always get 2 times lCount = -1, and fErrMsg is assigned 10014 both times, the 3rd times it works and shows correctly the expected information. I tried several combinations to allocate lBuffer, and every one fails with 10014 the first 2 times, and the third is goes. The client machine, where this code runs, has only IPv4 active. The UDP server runs both IPv6 and IPv4, but is only bound to Ipv4 at 0.0.0.0 Can someone shed some light? TIA, Clément Share this post Link to post
Remy Lebeau 1392 Posted November 12 (edited) Winsock error 10014 is WSAEFAULT. I don't know ICS's internals, but presumably fSender.ReceiveFrom() calls Winsock's recvfrom() function, whose documentation says: Quote WSAEFAULT The buffer pointed to by the buf or from parameters are not in the user address space, or the fromlen parameter is too small to accommodate the source address of the peer address. Your lFromLen variable is uninitialized, so your code is passing an indeterminate value to recvfrom() which exhibits undefined behavior. Sometimes the value is too small, sometimes it is not. You need to initialize your lFromLen variable to specify the size of your lFromSock variable before calling fSender.ReceiveFrom(). On a side note: you are treating lCount=0 as an error condition, but it is not. Unlike TCP, UDP messages can be 0 bytes in size. You should be calling WSAGetLastError() only if lCount is SOCKET_ERROR (-1). Edited November 12 by Remy Lebeau Share this post Link to post
Angus Robertson 574 Posted November 12 I would recommend you use the TIcsIpStrmLog streaming log component, look at the doSocketRemoteClick function in the Snippets sample which is TCP so needs a one line change for UDP, then data just arrives in an event. Angus Share this post Link to post
Clément 148 Posted November 12 I'll fix the code and take a look at the component. Thanks Share this post Link to post