Announcement

Collapse
No announcement yet.

TCP RECV -- Hangs when EOF = %FALSE

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • TCP RECV -- Hangs when EOF = %FALSE

    Code:
     FUNCTION START_TCP_LISTENER(HOST_STRING AS STRING, IP_PORT AS LONG) AS LONG
    
       LOCAL IP_LONG AS LONG
    
       HOST ADDR HOST_STRING TO IP_LONG
    
       TRY
         TCP OPEN SERVER ADDR IP_LONG PORT IP_PORT AS GL_LISTENING_FILE_NUMBER TIMEOUT 10
         'TEXT_TO_SCREEN "OPEN SERVER"
        CATCH
         FUNCTION = 1
         EXIT FUNCTION
       END TRY
    
       TRY
         TCP NOTIFY GL_LISTENING_FILE_NUMBER, SEND RECV ACCEPT CONNECT CLOSE TO GL_hDlg AS %TCP_EVENT
         'TEXT_TO_SCREEN "NOTIFY"
        CATCH
         FUNCTION = 1
         EXIT FUNCTION
       END TRY
    
       FUNCTION = 0
    
     END FUNCTION
    NOTE I am using TCP OPEN SERVER

    I have been working on improving an application that uses lots of TCP SEND and TCP RECV.
    In the past I have always called TCP RECV like this: TCP RECV FILE_NUMBER, 4096, PACKET_RECEIVE_BUFFER and always used TCP SEND FILE_NUMBER, SEND_BUFFER
    and made sure the LEN(SEND_BUFFER) was less than 4096.

    For testing purposes I tried this: TCP RECV FILE_NUMBER, 512, PACKET_RECEIVE_BUFFER and sent it TCP SEND FILE_NUMBER, SEND_BUFFER where LEN(SEND_BUFFER ) is greater than 512. In that condition the TCP RECV FILE_NUMBER, 512, PACKET_RECEIVE_BUFFER DOES NOT return EOF=0, what is does is wait the TIMEOUT period then it returns EOF=0. Then you can loop to collect the rest of the data from the buffer. To me this is exactly backwards. If the buffer (512) is full then the call to TCP RECV should return immediately.

    A point of interest. If you set to
    TCP RECV FILE_NUMBER, 65535, you will always get the entire receive buffer in the first RECV without a time out. If you set the timeout to 0 TCP RECV acts as advertised.

    So, I can't see any circumstances where the timeout in TCP RECV in the context of opened as SERVER does anything of value.




  • #2
    TCP OPEN TIMEOUT 10 only gives tcp recv 10 milliseconds (not seconds) to receive data before timing-out.









    https://duckduckgo.com instead of google

    Comment


    • #3
      True Mike - But if EOF is %False you are going back for more anyway.

      Comment


      • #4
        Does the CPU hit 100%
        https://duckduckgo.com instead of google

        Comment


        • #5
          David,
          This is how I do it:

          Code:
                      TCP OPEN SERVER PORT 1000 AS hTcp_Recv TIMEOUT 12000
          
                      IF ERR THEN
                          hTcp_Recv = 0
                          'CALL SHOW_NOTES_NO_WAIT("Could not open TCP/IP server 1 socket!")
                         ' call CLEAR_WAIT_CURSOR(93)
          
                          FUNCTION = 0
                          EXIT FUNCTION
                      ELSE
                          TCP NOTIFY hTcp_Recv, ACCEPT TO hWndMain AS %TCP_ACCEPT
                      END IF
          In WndProc

          Code:
              CASE %TCP_ACCEPT
                  'tcpaccept functions
                  call TCPAcceptCommand(wParam, lParam)
                  FUNCTION = 1
          
              CASE %TCP_STATUS
                  'tcpstatus functions
                  call TCPStatusCommand(wParam, lParam)
                  FUNCTION = 1
          Further processing commands

          Code:
          sub TCPAcceptCommand(BYVAL wParamX AS long, BYVAL lParamX AS long)
            SELECT CASE LO(WORD, lParamX)
          
                CASE %FD_ACCEPT
                    ' The socket is able to accept a new connection.
                    hEcho = FREEFILE
                    TCP ACCEPT hTcp_Recv AS hEcho
                    TCP NOTIFY hEcho, RECV CLOSE TO hWndMain AS %TCP_STATUS  'SEND | RECV | ACCEPT | CONNECT | CLOSE
          
            END SELECT
          END SUB
          
          
          SUB TCPStatusCommand(BYVAL wParamX AS long, BYVAL lParamX AS long)
            SELECT CASE LO(WORD, lParamX)
                'CASE %FD_WRITE
                '    ' The socket is ready for data to be written.
                '
                'CASE %FD_CONNECT
                '    ' The connection has been established.
          
                CASE %FD_READ
                    ' Data is available to be read from the socket.
                    IF hEcho <> %INVALID_SOCKET THEN
                        CALL READ_IN_TCP_DATA
                    ELSE
                        'hEcho = %INVALID_SOCKET
                        ' "* FD_READ Error!"
                    END IF
          
                CASE %FD_CLOSE
                    ' The socket has been closed
                    'TCP CLOSE hEcho
                    'hEcho = %INVALID_SOCKET
          
            END SELECT
          END SUB
          READ_IN_TCP_DATA captures the data and adds it to a FIFO buffer to be handled by a received data processing thread.

          Comment


          • #6

            TCP NOTIFY GL_LISTENING_FILE_NUMBER, SEND RECV ACCEPT CONNECT CLOSE TO GL_hDlg AS %TCP_EVENT
            TCP NOTIFY hTcp_Recv, ACCEPT TO hWndMain AS %TCP_ACCEPT

            With a timeout of 10ms checking for timeout is out of the question.
            How do you know when the transmission has completed other than closing the connection.
            Do you know the number of bytes to be received? Just asking because there are better ways.

            There is no TCP Recv loop shown to hang.
            This is from the docs. Which should be improved because it concatenates Inbuffer.
            DO
            TCP RECV hEcho, 1024, buffer
            IF LEN(buffer) = 0 OR ISTRUE ERR THEN EXIT LOOP
            InBuffer = InBuffer + buffer '
            LOOP
            https://duckduckgo.com instead of google

            Comment


            • #7
              Mike,

              How would you improve the "concatenates Inbuffer." ?? Fixed length string?



              If I set the TIMEOUT to 5000 and the RECV number of bytes to get to 128 (TCP RECV FILE_NUMBER, 128, PACKET_RECEIVE_BUFFER ) then each time there are 128 bytes the RECV succeeds. However if we are at the end of the file and there are less than 128 bytes it waits the timeout period. I used 128 to demonstrate what a looping RECV does. The best performance I have gotten is using this: TCP RECV FILE_NUMBER, 65536, PACKET_RECEIVE_BUFFER.

              99.99% of the time I can get the entire transmission in the first TCP RECV after the event has fired and there is no need to loop the receive. Most of what I run into are TCP RECV after the event fires.

              Here is how it runs:


              REMOTE IP 98.0.53.96
              %FD_READ - TIMER=061303.2630

              ----- START OF TCP RECV ---------------------------------------------
              THIS RECV - RECEIVED BYTE COUNT = 39420
              A ACCUMULATING RECEIVED BYTE COUNT = 39420
              LOOP IS DONE IT TOOK THIS MANY LOOPS = 1
              FINAL STATIC ACCUMULATING RECEIVED BYTE COUNT = 39420
              END OF REC -----------------------

              %FD_READ - TIMER=061303.3730

              ----- START OF TCP RECV ---------------------------------------------
              THIS RECV - RECEIVED BYTE COUNT = 65536
              A ACCUMULATING RECEIVED BYTE COUNT = 104956
              THIS RECV - RECEIVED BYTE COUNT = 45054
              A ACCUMULATING RECEIVED BYTE COUNT = 150010
              LOOP IS DONE IT TOOK THIS MANY LOOPS = 2
              FINAL STATIC ACCUMULATING RECEIVED BYTE COUNT = 150010
              END OF REC -----------------------

              %FD_READ - TIMER=061303.5470

              ----- START OF TCP RECV ---------------------------------------------
              THIS RECV - RECEIVED BYTE COUNT = 0
              A ACCUMULATING RECEIVED BYTE COUNT = 150010
              LOOP IS DONE IT TOOK THIS MANY LOOPS = 1
              FINAL STATIC ACCUMULATING RECEIVED BYTE COUNT = 150010
              END OF REC -----------------------




              Comment


              • #8
                David,
                LOOP UNTIL sBufferTCP = "" OR ISTRUE EOF(hEcho) OR ISTRUE ERR
                See below
                Code:
                '_________________________________________________________________
                '
                '   SUB  READ_IN_TCP_DATA
                '_________________________________________________________________
                
                SUB READ_IN_TCP_DATA
                  LOCAL sBufferTCP AS STRING
                  LOCAL sPacketTCP AS STRING
                
                  sBufferTCP = ""
                  sPacketTCP = ""
                
                  ' Perform a receive-loop until there is no data left (ie, the end of stream)
                  DO
                      TCP RECV hEcho, 1024, sBufferTCP
                      sPacketTCP = sPacketTCP + sBufferTCP
                  LOOP UNTIL sBufferTCP = "" OR ISTRUE EOF(hEcho) OR ISTRUE ERR
                
                      IF INSTR(sPacketTCP, "Something Identifiable In The Message") > 0 THEN
                          'capture the message in the gsReceiveBuffer string array
                              giWritingToBufferRecv = 1    'lock FIFO buffer
                              gsReceiveBuffer = gsReceiveBuffer + sPacketTCP + "|+|"
                              giWritingToBufferRecv = 0    'Unlock FIFO buffer
                        END IF
                END SUB

                Comment


                • #9
                  David,

                  Here is a multi-threaded echo server.

                  It fills a string using mid$ to the length of bytes to be received.
                  StringBuilder or filling an array could have been used.
                  Eliminating concatenation can greatly increase performance on large files.

                  First 6-bytes (header) modify to anything you want.
                  4-bytes - number of bytes being sent
                  2-bytes - user id (verification)

                  What makes it pretty fast is that when the number of bytes left to receive hits 0 it exits the first loop.
                  It remains connected for the TCP time-out or either side terminates.
                  This enables modifying for client/server applications. Add encryption and whatever you want.


                  Miniserver.bas
                  Code:
                  #COMPILE EXE "miniserver"
                  #PBFORMS CREATED V2.01
                  
                  $ValidUser = CHR$(1,2)  'id following first 4-bytes
                  $Host = "192.168.0.2"  
                  %Port =  12345
                  %BeepOnConnect = 0      'beep if someone connects
                  %BeepOnDisconnect=0
                  %BeepIfLogUpdated=0     'each entry causes a beep
                  %LogEachConnect   =0    'write each connect to log
                  %LogEachDisconnect=0    'write each disconn to log
                  %LogBytesToReceive=0    '
                  %LogFinalResult   =1    'show bytes received
                  
                  %TCP_TIMEOUT = 80000
                  %ListenFileNumber = 9999
                  %Tcp_Notify = %WM_USER + 4093
                  %LB_SETHORIZONTALEXTENT= &H194???
                  %ANSI_CHARSET = 0?
                  GLOBAL ghDlg AS DWORD, gsAll AS STRING 'only for testing
                  '-----------------------------------------------------------------------------------
                  #PBFORMS BEGIN INCLUDES
                  #INCLUDE ONCE "WIN32API.INC"
                  #PBFORMS END INCLUDES
                  #PBFORMS BEGIN CONSTANTS
                  %TEXTBOX1    = 1001
                  %IDM_CLEAR   = 2001
                  %IDM_DISPLAY = 2002
                  
                  #PBFORMS END CONSTANTS
                  #PBFORMS DECLARATIONS
                  
                  '------------------------------------------------------------------------------
                  THREAD FUNCTION ConnectionMain(BYVAL tcpfilenumber AS LONG) AS LONG
                  
                   IF %BeepOnConnect  THEN BEEP
                   IF %LogEachConnect THEN
                    Logit USING$("Connect #",tcpfilenumber)
                   END IF
                   LOCAL sPacket          AS STRING
                   LOCAL sBuffer          AS STRING
                   LOCAL BytesToReceive   AS DWORD
                   LOCAL BytesLeft        AS DWORD
                   LOCAL StartByte        AS DWORD
                  
                  DO 'first 4-bytes is length of data to receive, 2-byte $ValidUser
                   sPacket = ""
                  
                   TCP RECV tcpFilenumber,6,sBuffer
                   IF ERR OR LEN(sBuffer) = 0 THEN EXIT DO
                   IF LEN(sBuffer) < 6 THEN logit USING$("[# byte_, needed 6]",LEN(sBuffer)):BEEP:SLEEP %TCP_TIMEOUT:EXIT DO '(wait,browsers retry) close, finish thread
                   IF MID$(sBuffer,5) <> $ValidUser THEN
                      BEEP:logit "invalid user, SLEEP" + STR$(%TCP_TIMEOUT)
                      SLEEP %TCP_TIMEOUT
                      BEEP:logit "tired of waiting, so finishing thread"
                      EXIT DO 'then TCP CLOSE, exit thread
                   END IF
                  
                   BytesToReceive  = CVDWD(sBuffer)  'don't process strings over 100 (500MB about max in 32-bit)
                   IF bytesToReceive > 200000000 THEN logit USING$("#, over 200 million bytes",BytesToReceive):EXIT DO
                  
                   BytesLeft = BytesToReceive
                   IF ERR OR BytesLeft = 0 THEN EXIT DO 'nothing left to do
                   sPacket = SPACE$(BytesToReceive) 'allocate space once
                   StartByte = 1
                   IF %LogBytesToReceive THEN logit USING$("--------Bytes to receive #,--------",BytesToReceive)
                   DO
                    TCP RECV tcpfilenumber,BytesLeft, sBuffer
                    IF ERR OR LEN(sBuffer) = 0 THEN EXIT DO
                  
                    MID$(sPacket,StartByte) = sBuffer
                    StartByte = StartByte + LEN(sBuffer)
                    BytesLeft = BytesLeft-LEN(sBuffer)
                  
                    IF BytesLeft = 0  THEN '<----------------------- RESULTS
                     IF %LogFinalResult THEN logit USING$("#, bytes (#)",LEN(sPacket),tcpfilenumber)
                     TCP SEND TcpFileNumber, MKDWD$(LEN(sPacket)) + $ValidUser + sPacket
                     EXIT DO
                    END IF
                   LOOP
                   'do not disconnect, and wait for more data
                  LOOP
                  
                  'DISCONNECT AND FINISH THIS THREAD
                  
                   SELECT CASE AS LONG ERR
                    CASE  0
                     IF %LogEachDisConnect THEN
                       Logit USING$("Disconnect #",tcpfilenumber)
                     END IF
                    CASE 24  :Logit USING$("time-out thread #",tcpfilenumber)
                    CASE 57  :logit USING$("dropped connection #",tcpfilenumber,tcpfilenumber)
                    CASE ELSE:logit USING$("untrapped error # in thread #",ERR,tcpfilenumber)
                   END SELECT
                  
                   TCP CLOSE tcpfilenumber
                  
                   IF %BeepOnDisconnect THEN BEEP
                  
                  END FUNCTION
                  
                  FUNCTION PBMAIN()
                    TheDialog 0
                  END FUNCTION
                  
                  FUNCTION TheDialog(BYVAL hParent AS DWORD) AS LONG
                    LOCAL lRslt AS LONG
                  #PBFORMS BEGIN DIALOG %IDD_DIALOG1->%IDR_MENU1->
                    LOCAL hDlg   AS DWORD
                    LOCAL hFont1 AS DWORD
                  
                    DIALOG NEW hParent, "", ,, 662, 364, %WS_POPUP OR %WS_BORDER OR _
                      %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
                      %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR _
                      %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR _
                      %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                    CONTROL ADD TEXTBOX, hDlg, %TEXTBOX1, "", 5, 10, 650, 327, %WS_CHILD OR _
                      %WS_VISIBLE OR %WS_HSCROLL OR %WS_VSCROLL OR %ES_LEFT OR %ES_MULTILINE _
                      OR %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT _
                      OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
                  
                    FONT NEW "Courier New", 8, 0, %ANSI_CHARSET TO hFont1
                  
                    CONTROL SET FONT hDlg, %TEXTBOX1, hFont1
                  
                    AttachMENU1 hDlg
                  #PBFORMS END DIALOG
                    ghDlg = hDlg
                    StartListener
                    DIALOG SHOW MODAL hDlg CALL MyCallBack
                    FUNCTION = lRslt
                  END FUNCTION
                  '------------------------------------------------------------------------------
                  SUB LogIt(s AS STRING) THREADSAFE
                   s = TIME$ + " " + s
                   IF %BeepIfLogUpdated THEN BEEP
                   gsAll+=s + $CRLF
                   CONTROL SET TEXT ghDlg, %TEXTBOX1,gsAll
                   'CONTROL SEND ghDlg,%TEXTBOX1,%WM_VSCROLL,%SB_BOTTOM,0  'takes time!
                  END SUB
                  '------------------------------------------------------------------------------
                  FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD
                  #PBFORMS BEGIN MENU %IDR_MENU1->%IDD_DIALOG1
                    LOCAL hMenu   AS DWORD
                  
                    MENU NEW BAR TO hMenu
                    MENU ADD STRING, hMenu, "Clear", %IDM_CLEAR, %MF_ENABLED
                    MENU ADD STRING, hMenu, "Display", %IDM_DISPLAY, %MF_ENABLED
                  
                    MENU ATTACH hMenu, hDlg
                  #PBFORMS END MENU
                    FUNCTION = hMenu
                  END FUNCTION
                  '------------------------------------------------------------------------------
                  SUB StartListener
                   LOCAL lhIPAddress    AS DWORD   'listen ip as dword
                   LOCAL nListenSocket  AS DWORD   'listen socket
                  
                   HOST ADDR $Host TO lhIPAddress  'Convert to IP addr
                   IF ISFALSE lhIPAddress THEN LogIt "Invalid IP Address " + $Host
                  
                   TCP OPEN SERVER ADDR lhIPAddress PORT %Port AS %ListenFileNumber TIMEOUT %TCP_TIMEOUT
                   IF ERR THEN
                     ? "Unable to open port " + STR$(%Port) + " on host " & $Host,%MB_SYSTEMMODAL,ERROR$ + STR$(ERR)
                     END
                   END IF
                   'nListenSocket = FILEATTR(gListenFileNumber, 2)  'only 1 listen socket so won't need it
                   TCP NOTIFY %ListenFileNumber, ACCEPT TO ghDlg AS %Tcp_Notify        'notify of connections
                   DIALOG SET TEXT ghDlg,USING$("host &     port #     TimeOut # ms",$Host,%Port,%TCP_TIMEOUT)
                  END SUB
                  
                  '------------------------------------------------------------------------------
                  CALLBACK FUNCTION MyCallBack
                    LOCAL NewTcpFileNumber,h AS LONG
                  
                   SELECT CASE AS LONG CB.MSG
                  
                    CASE %TCP_NOTIFY
                     IF LO(WORD, CB.LPARAM) = %FD_ACCEPT THEN
                      NewTcpFileNumber = FREEFILE
                      TCP ACCEPT %ListenFileNumber AS NewTcpFileNumber
                      THREAD CREATE ConnectionMain(NewTcpFileNumber) TO h
                      THREAD CLOSE h TO h
                      'SLEEP 5 'couldn't hurt
                     END IF
                  
                     CASE %WM_INITDIALOG
                       ghDlg = CB.HNDL
                  
                     CASE %WM_COMMAND
                      SELECT CASE AS LONG CB.CTL
                  
                        CASE %IDM_CLEAR
                         gsAll = ""
                         CONTROL SET TEXT CB.HNDL,%TEXTBOX1,gsAll
                  
                        CASE %IDM_Display
                         CONTROL SET TEXT ghDlg, %TEXTBOX1,USING$("Total bytes #",LEN(gsAll))
                         CONTROL SEND ghDlg,%TEXTBOX1,%WM_VSCROLL,%SB_BOTTOM,0
                      END SELECT
                  
                   END SELECT
                  END FUNCTION
                  MiniClient.bas
                  Code:
                  #DIM ALL
                  #COMPILE EXE "miniclient.exe"
                  
                  FUNCTION PBMAIN AS LONG 'miniclient.bas
                    LOCAL ecode,portnumber AS LONG,suser,shost,sSend,sReceive AS STRING
                    sUser=CHR$(1,2)
                    sHost = "192.168.0.2"  :portnumber = 12345
                    sSend = STRING$(100,0)
                    ecode=senddata(suser,shost,portnumber&,sSend,sReceive)
                    IF ecode= 0 THEN
                      ? USING$(CHR$("#, bytes sent",$CR,"#, bytes recv",$CR),LEN(sSend),LEN(sReceive)),,"Echo Host " + sHost
                    ELSE
                      ? "Error"+STR$(ecode),,sHost + " at " + TIME$
                    END IF
                  END FUNCTION
                  
                  FUNCTION senddata(sUser AS STRING,sHost AS STRING,portnumber AS LONG,sSend AS STRING,sReceive AS STRING) AS LONG
                    LOCAL TcpFileNumber AS LONG
                    LOCAL sBuffer          AS STRING
                    LOCAL BytesToReceive   AS DWORD
                    LOCAL BytesLeft        AS DWORD
                    LOCAL BytesReceived    AS DWORD
                    LOCAL StartByte        AS DWORD
                    TcpFileNumber = FREEFILE   'send data:4-bytes dword length of sSend$ + sUser$ + sSend$
                    TCP OPEN PORT PortNumber AT shost AS #TcpFileNumber
                    IF ERR THEN FUNCTION = ERR:EXIT FUNCTION
                  
                    TCP SEND TcpFileNumber, MKDWD$(LEN(sSend)) + suser + sSend
                    IF ERR THEN FUNCTION = ERR:TCP CLOSE #TcpFileNumber:EXIT FUNCTION
                    FUNCTION = ReceiveData(TcpFileNumber,sUser,sReceive) 'receive response from server
                  
                    TCP CLOSE tcpfilenumber
                  END FUNCTION
                  
                  FUNCTION ReceiveData(tcpFileNumber AS LONG,sUser AS STRING,sPacket AS STRING) AS LONG
                    LOCAL sBuffer          AS STRING
                    LOCAL BytesToReceive   AS DWORD
                    LOCAL BytesLeft        AS DWORD
                    LOCAL StartByte        AS DWORD
                    DO
                      sPacket = ""
                      TCP RECV tcpFilenumber,6,sBuffer
                      IF ERR THEN FUNCTION = ERR:EXIT DO                        'transmit error
                      SELECT CASE LEN(sBuffer)                                  'check sBuffer
                        CASE 0:ERR=1:EXIT DO                                    'no response             (error 1)
                        CASE 6:IF MID$(sBuffer,5) <> sUser THEN ERR = 2:EXIT DO 'invalid/incorrect user  (error 2)
                        CASE ELSE:ERR = 3:EXIT DO                               'invalid format received (error 3)
                      END SELECT
                      BytesToReceive  = CVDWD(sBuffer)  'don't process strings over 100 (500MB about max in 32-bit)
                      IF bytesToReceive > 200000000 THEN ? USING$("#, over 200 million bytes&",BytesToReceive,$CRLF):EXIT DO
                      BytesLeft = BytesToReceive
                      IF ERR OR BytesLeft = 0 THEN EXIT DO 'nothing left to do
                      sPacket = SPACE$(BytesToReceive) 'allocate space once
                      StartByte = 1
                      DO
                        TCP RECV tcpfilenumber,BytesLeft, sBuffer
                        IF ERR OR LEN(sBuffer) = 0 THEN EXIT DO
                        MID$(sPacket,StartByte) = sBuffer
                        StartByte = StartByte + LEN(sBuffer)
                        BytesLeft = BytesLeft-LEN(sBuffer)
                        IF BytesLeft = 0 THEN EXIT,EXIT 'we are done, servers EXIT only once to wait for more data
                      LOOP
                    LOOP
                    FUNCTION = ERR
                  END FUNCTION

                  https://duckduckgo.com instead of google

                  Comment


                  • #10
                    Nice one Mike!!

                    Comment


                    • #11
                      I can't see a good reason to put TCP RECV in a loop as long as you are getting notifications as set in TCP NOTIFY. From what I have seen you are signaled as soon as any data is in the TCP buffer and you are not signaled again until you preform a TCP RECV - assuming more data arrives. So you keep getting signaled as long as the data keeps coming. So I guess i am saying do either TCP RECV looping or just respond to the event message - end result is the same except responding to events keeps windows happy.

                      To answer some questions - Yes i do know how many bytes to expect and or the sender can disconnect when done. Every "packet" has a header with some useful data in it, sometimes it has an MD5 too.

                      Comment


                      • #12
                        David,
                        I cannot see it either. All you need is a TCP NOTIFY implemented as in post #5.

                        Code:
                        TCP NOTIFY hTcp_Recv, ACCEPT TO hWndMain AS %TCP_ACCEPT

                        Comment


                        • #13
                          Jim, I missed that detail in #5.

                          So this begs the question - If one is using TCP NOTIFY then are you doing asynch receive - does that mean we are already doing overlapped communications? When I do TCP SEND there is never any delay (not blocking) and same with TCP RECV.

                          Comment

                          Working...
                          X