Archived Forum Post

Index of archived forum posts

Question:

AsyncReceiveFinished unexpected behavior

Feb 27 '14 at 11:54

I have an issue with AsyncReceiveFinished property.
From documentation it is a property designated to know when the Receive process is finished.
But from your sample loop

DO WHILE (THISFORM.oleSocket.AsyncReceiveFinished <> 1)
  &&  Sleep 1 second.
  THISFORM.oleSocket.SleepMs(100)
  && do another task while waiting to finish
ENDDO

It seems to pass thru the loop only once if AsyncReceiveFinished returns 0 and then wait until AsyncReceiveFinished became 1 (i.e. no second pass) before to go on.

For testing purpose I put all in a FOR/NEXT like below.

    T_nSuccess = THISFORM.oleSocket.AsyncReceiveToCRLF()

    IF (T_nSuccess <> 1) THEN 
        THISFORM.AddToLog("AsyncReceiveToCRLF Error:" +CR_LF+THISFORM.oleSocket.LastErrorText)
        RETURN .F.
    ENDIF

    T_cnt = 0
    FOR T_Cnt = 1 TO 10
        THISFORM.AddToLog("Wait for AsyncReceiveFinished (STRING):"+ ;
                    STR(T_cnt )+ ;
                    '/THISFORM.oleSocket.AsyncReceiveFinished:'+ ;
                    TRANSFORM(THISFORM.oleSocket.AsyncReceiveFinished))

        THISFORM.oleSocket.SleepMs(100)
    NEXT

The resulted log is:

19:36:05 Wait for AsyncReceiveFinished (STRING):         1/THISFORM.oleSocket.AsyncReceiveFinished:0
19:36:38 Wait for AsyncReceiveFinished (STRING):         2/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:38 Wait for AsyncReceiveFinished (STRING):         3/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:38 Wait for AsyncReceiveFinished (STRING):         4/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:38 Wait for AsyncReceiveFinished (STRING):         5/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:38 Wait for AsyncReceiveFinished (STRING):         6/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:39 Wait for AsyncReceiveFinished (STRING):         7/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:39 Wait for AsyncReceiveFinished (STRING):         8/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:39 Wait for AsyncReceiveFinished (STRING):         9/THISFORM.oleSocket.AsyncReceiveFinished:1
19:36:39 Wait for AsyncReceiveFinished (STRING):        10/THISFORM.oleSocket.AsyncReceiveFinished:1

As you can see between the first and the second line is a delay of 33 seconds, well over 0.1 seconds delay from loop.

There is any reason for this behavior? I am missing something? How can I really loop and execute other tasks in that loop waiting for AsuncReceive to finish? This is the real goal for an async connection isn't it?


Answer

I examined the internal code, but the AsyncReceiveFinished property access does nothing more than return a member variable. (In other words, the body of the internal function is essentially one line of code.)

Please try this new build: http://www.chilkatsoft.com/preRelease/ChilkatSocket-9.5.0-win32.zip

If the problem remains, examine the oleSocket.LastErrorText after calling oleSocket.AsyncReceiveToCRLF, just to make sure you're using this new build.


Answer

Thank you for your answer.
The new version don't solve my issue.
The previous code was part of a much complicated application.
I am trying now to isolate the issue, so I made a small test application, almost a perfect copy of your sample from documentation, with the following code:

Ps_temp = 'TEMP\'

* set the main app path as default path
gcAppRoot =LEFT(SYS(16),RAT('\',SYS(16)))
SET DEFA TO (gcAppRoot)
SET ALTERNATE TO AsyncTest.txt
SET ALTERNATE ON

ON ERROR DO ErrLog WITH ;
    ERROR(), MESSAGE(), MESSAGE(1), PROGRAM(), LINENO(1)

LOCAL loSocket
LOCAL lnSuccess
LOCAL lnUseSsl
LOCAL lnMaxWaitMillisec
LOCAL lcRemoteHost
LOCAL lnRemotePort

loSocket = CreateObject('Chilkat.Socket')

lnSuccess = loSocket.UnlockComponent("MY_UNLOCK_CODE")
IF (lnSuccess <> 1) THEN
    ? loSocket.LastErrorText
    QUIT
ENDIF

lnUseSsl = 0

lnMaxWaitMillisec = 20000

*  The remote hostname may be an IP address, a domain name,
*  or "localhost".  You'll need to change this:

lcRemoteHost = "127.0.0.1"

lnRemotePort = 25000

*  Connect to the remote host asynchronously in a background thread.
lnSuccess = loSocket.AsyncConnectStart(lcRemoteHost,lnRemotePort,lnUseSsl,lnMaxWaitMillisec)
IF (lnSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.LastErrorText)
    QUIT
ENDIF

*  Wait for the socket to become connected...
DO WHILE (loSocket.AsyncConnectFinished <> 1)
    *  Sleep 1 second.
    loSocket.SleepMs(100)
ENDDO

*  Did the connect fail?
IF (loSocket.AsyncConnectSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.AsyncConnectLog)
    QUIT
ENDIF

*  Set maximum timeouts for reading an writing (in millisec)
*loSocket.MaxReadIdleMs = 20000
*loSocket.MaxSendIdleMs = 20000
loSocket.MaxReadIdleMs = 0  && wait until receive something
loSocket.MaxSendIdleMs = 0

CRLF = CHR(13)+CHR(10)

DELETE FILE 'C:\VERIFONE\Socket.log'
loSocket.DebugLogFilePath = 'C:\VERIFONE\Socket.log'
loSocket.VerboseLogging = 1

*  Send a request:
lnSuccess = loSocket.AsyncSendString("L2,BRANCHC,PASSWORD,"+CRLF)
IF (lnSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.LastErrorText)
    QUIT
ENDIF

*  Wait for the send to finish
?TRANSFORM(SECONDS())+' Start LOOP Wait for AsyncSendFinished:'
T_cnt = 0
DO WHILE (loSocket.AsyncSendFinished <> 1)
    T_cnt = T_cnt + 1
    *  Sleep 1 second.
*    loSocket.SleepMs(100)
    T_msg = TRANSFORM(SECONDS())+' ('+TRANSFORM(T_cnt)+') Wait for AsyncSendFinished :'
    ?T_msg
ENDDO
?TRANSFORM(SECONDS())+' Exit LOOP Wait for AsyncSendFinished:'

*  Did the send fail?
IF (loSocket.AsyncSendSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.AsyncSendLog)
    QUIT
ENDIF

*  The server (in this example) is going to send a "Hello Client! -EOM-"
*  message.  Begin reading asynchronously in a background thread:

?TRANSFORM(SECONDS())+ ' Start AsyncReceiveToCRLF:'

lnSuccess = loSocket.AsyncReceiveToCRLF()

*?TRANSFORM(SECONDS())+' -------------- LastErrorText -----------------'
*?TRANSFORM(SECONDS())+' '+loSocket.LastErrorText
*?TRANSFORM(SECONDS())+' ----------------------------------------------'

IF (lnSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.LastErrorText)
    QUIT
ENDIF

*  Wait for the background read to finish

?TRANSFORM(SECONDS())+' Start LOOP Wait for AsyncReceiveFinished:'

T_cnt = 0
DO WHILE (loSocket.AsyncReceiveFinished <> 1)
    T_cnt = T_cnt + 1
    *  Sleep 1 second.
*    loSocket.SleepMs(100)
    T_msg = TRANSFORM(SECONDS())+' ('+TRANSFORM(T_cnt)+') Wait for AsyncReceiveFinished:'
    ?T_msg
ENDDO

?TRANSFORM(SECONDS())+' Exit LOOP Wait for AsyncReceiveFinished:'

*  Did the receive fail?
IF (loSocket.AsyncReceiveSuccess <> 1) THEN
    =MESSAGEBOX(loSocket.AsyncReceiveLog)
    QUIT
ENDIF

?TRANSFORM(SECONDS())+' End AsyncReceiveSuccess:'

*  Display the received message:
?'--- Received Message ---'
? loSocket.AsyncReceivedString

*  Close the connection with the server
*  Wait a max of 20 seconds (20000 millsec)
loSocket.Close(20000)

PROCEDURE ErrLog
LPARAMETERS lnErrorNo, lcMessage, lcErrorLine, lcModule, lnErrorLineNo

If I run the code above (i.e. no delay in loop) I get the following result:

59247.806 Start LOOP Wait for AsyncSendFinished:
59247.806 Exit LOOP Wait for AsyncSendFinished:
59247.811 Start AsyncReceiveToCRLF:
59247.832 Start LOOP Wait for AsyncReceiveFinished:
59247.832 (1) Wait for AsyncReceiveFinished:
59247.833 (2) Wait for AsyncReceiveFinished:
59247.833 (3) Wait for AsyncReceiveFinished:
59247.833 (4) Wait for AsyncReceiveFinished:
59247.833 (5) Wait for AsyncReceiveFinished:
59247.834 (6) Wait for AsyncReceiveFinished:
59247.834 (7) Wait for AsyncReceiveFinished:
59247.834 (8) Wait for AsyncReceiveFinished:
59247.835 (9) Wait for AsyncReceiveFinished:
59247.835 (10) Wait for AsyncReceiveFinished:
59247.835 (11) Wait for AsyncReceiveFinished:
59247.835 (12) Wait for AsyncReceiveFinished:
59247.836 (13) Wait for AsyncReceiveFinished:
59247.836 (14) Wait for AsyncReceiveFinished:
59247.836 (15) Wait for AsyncReceiveFinished:
59247.836 (16) Wait for AsyncReceiveFinished:
59247.837 (17) Wait for AsyncReceiveFinished:
59247.837 (18) Wait for AsyncReceiveFinished:
59247.837 (19) Wait for AsyncReceiveFinished:
59247.838 (20) Wait for AsyncReceiveFinished:
59247.838 (21) Wait for AsyncReceiveFinished:
59247.838 (22) Wait for AsyncReceiveFinished:
59247.838 (23) Wait for AsyncReceiveFinished:
59247.839 (24) Wait for AsyncReceiveFinished:
59247.839 (25) Wait for AsyncReceiveFinished:
59247.839 (26) Wait for AsyncReceiveFinished:
59247.840 (27) Wait for AsyncReceiveFinished:
59247.840 (28) Wait for AsyncReceiveFinished:
59247.840 (29) Wait for AsyncReceiveFinished:
59247.840 (30) Wait for AsyncReceiveFinished:
59247.841 (31) Wait for AsyncReceiveFinished:
59247.841 (32) Wait for AsyncReceiveFinished:
59247.841 (33) Wait for AsyncReceiveFinished:
59247.842 (34) Wait for AsyncReceiveFinished:
59247.842 (35) Wait for AsyncReceiveFinished:
59247.842 (36) Wait for AsyncReceiveFinished:
59247.844 (37) Wait for AsyncReceiveFinished:
59247.846 (38) Wait for AsyncReceiveFinished:
59247.848 (39) Wait for AsyncReceiveFinished:
59247.852 (40) Wait for AsyncReceiveFinished:
59247.854 (41) Wait for AsyncReceiveFinished:
59247.856 (42) Wait for AsyncReceiveFinished:
59247.857 (43) Wait for AsyncReceiveFinished:
59247.859 (44) Wait for AsyncReceiveFinished:
59247.861 (45) Wait for AsyncReceiveFinished:
59247.862 (46) Wait for AsyncReceiveFinished:
59282.925 Exit LOOP Wait for AsyncReceiveFinished:
59282.930 End AsyncReceiveSuccess:
--- Received Message ---
0,1,,,,,,,,,,,,,,,,Download Successful


As you can see, now it able to pass 46 times thru loop before freeze then wait 35 seconds to receive the string and continue.

If I remove the comments from delay (SleepMs = 100) the result is:

58232.673 Start LOOP Wait for AsyncSendFinished:
58232.673 Exit LOOP Wait for AsyncSendFinished:
58232.673 Start AsyncReceiveToCRLF:
-------------- LastErrorText -----------------
ChilkatLog:
  AsyncReceiveToCRLF:
    DllDate: Feb 27 2014
    ChilkatVersion: 9.5.0.14
    UnlockPrefix: TAHIRKSocket
    Username: SEAFRESH-POP:Seafresh
    Architecture: Little Endian; 32-bit
    Language: ActiveX
    VerboseLogging: 1
    fd: 0x220
    objectId: 1
    Success.
  --AsyncReceiveToCRLF
--ChilkatLog
----------------------------------------------
58232.709 Start LOOP Wait for AsyncReceiveFinished:
58232.810 (1) Wait for AsyncReceiveFinished:
58271.634 Exit LOOP Wait for AsyncReceiveFinished:
58271.634 End AsyncReceiveSuccess:
--- Received Message ---
0,1,,,,,,,,,,,,,,,,Download Successful


Now there is only one pass thru loop and then again the same wait of about 35 seconds.
It looks like from some reasons the async process is stopped a little while after AsyncReceiveToCRLF starts and it is resumed only after the string is received.

Few words about my environment:
* OS Win7
* a third party application (Sentinel from Verifone) which answer to my strings

Any idea about a possible way to solve this issue is more than welcome.