Announcement

Collapse
No announcement yet.

tcp send/recv ?

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

  • tcp send/recv ?

    Hello all...

    Is there any possiblility that a string sent with "tcp send hsock, buffer", could become fragmented so that ONE read with "tcp recv, hsock, 8000, buffer" would not receive the whole contents of the string ?


    here is an example...

    tcp send hsock, "mark smit"

    tcp recv hsock, 8000, buff1
    tcp recv hsock, 8000, buff2

    buff1 = "mar"
    buff2 = "k smit"

    Could this happen ?

    Cheers!

  • #2
    I would believe this COULD happen in fact.
    TCP/IP is a byte oriented protocol, it does not care waht the data does on the wire and is almost ALWAYS fragmented in one way or another..
    Although this may cure your problem, you will have the same issue I had in that you have to parse your buffer to separate it:

    Code:
    Do
      Tcp Recv #hTcp,4096, buffer
      WebIn = WebIn + buffer
    Loop While Len(buffer)
    Tcp Close hTcp
    
    lCount = Tally(WebIn,$CR) 
    For lLoop = 1 To 10
        sInArray = Parse$(WebIn,$CR,lLoop) 
        'Do whatever
    
    Next
    That should solve your problem, but you will have to parse based on whatever the expected string is AFTER you do that, ie mark smit would be parsed by the " " (name=parse$(buffer," ",1)


    PS, Lance, Jim, I learn quick eh? LOL
    Scott

    ------------------
    Scott
    mailto:[email protected][email protected]</A>

    [This message has been edited by Scott Turchin (edited May 10, 2000).]
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

    Comment


    • #3
      Where possible, it is always a good idea to build in your own form of data validation, so that if a data packet does manage to go astray, your code will be able to handle it without crashing.



      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Hello again...

        I have already tried your example code above to ensure that the FULL data packet has been read in.

        do
        tcp recv hsock, 2048, buffer
        packet = (packet & buffer)
        loop while len(buffer)

        On my machine the above loop hangs up on the last read. The only way to break to loop was to "Task Manager it to death" or close the hsock connection via the sending program. I have tried the above example in a modified way so that i could see what was happening.

        do
        tcp recv hsock, 8, buffer
        packet = (packet & buffer)
        msgbox "[" & buffer & "]"
        loop while len(buffer)

        note: the brackets are just to show any white space...

        This example displays "[]" on the last read and then when I close the connection another %FD_READ message seems to be sent because another "MSGBOX" pops up with the full message packet in brackets "[]".

        Cheers!

        ------------------

        Comment


        • #5
          mark --
          try this. if you haven't dial-up, you should correct port and name of server in tcp open (be careful here).
          <font face="courier new, courier" size="3"><pre>
          #compile exe
          #register none
          #dim all
          #include "win32api.inc"

          function pbmain
          dim buffer as string, kbuffer as long, i as long
          tcp open port 80 at "www.powerbasic.com" as #1 timeout 5000
          tcp print #1, "get http://www.powerbasic.com/support/pb...ead.php?t=2199 http/1.0"
          tcp print #1, "
          kbuffer = 2048: buffer$ = space$(kbuffer)
          open "tmp.html" for output as #2
          do
          tcp recv #1, kbuffer, buffer
          if len(buffer) = 0 then exit do
          print #2, buffer;
          loop
          close #2
          tcp close #1
          open "tmp.html" for binary as #2: get$ #2, lof(2), buffer: close #2
          open "tmp.html" for output as #2
          print #2, "------------- this web-page was downloaded by pb at " + time$ + " ----------<br><br>"
          print #2, "
          i = instr(buffer, $crlf + $crlf)
          if ucase$(left$(buffer, 5)) = "http/" and i then print #2, mid$(buffer, i + 4); else _
          print #2, buffer;
          close #2
          shellexecute %hwnd_desktop, "open", "tmp.html", byval 0, byval 0, %sw_shownormal
          end function
          [/CODE]



          ------------------

          Comment


          • #6
            Hello Semen !

            Thank you for your reply but I am having a hard time understanding why the port and address would be my problem. reason being that I do have the right port and address and I am able to retreive a partial message but on the last read (ie the end of the message) my program gets stuck in the loop until the connection is closed.

            Cheers !

            ------------------

            Comment


            • #7
              Mark --
              post not workable fragment from your program (but from Compile Exe to End Function of PbMain).
              Perhaps, your done something wrong somewhere or do not use Register None.
              I use PB/TCP-based utility in commercial program w/o problem.

              ------------------

              Comment


              • #8
                Hello Again Semen !

                Here is my code that did not work, in fact it causes a general protection fault. I hope i've posted the code write...

                {code}
                #compile exe
                #register none
                #include "win32api.inc"
                #include "wsock32.inc"

                %WM_SERVERNOTIFY = 8000
                %IDBUTTON = 9000

                function FormatIP(byval IPAddress as long) as string
                dim address as string

                address = mkl$(IPAddress)
                function = format$(asc(address, 1), "#.") & _
                format$(asc(address, 2), "#.") & _
                format$(asc(address, 3), "#.") & _
                format$(asc(address, 4), "#")

                end function

                callback function dlgproc() as long
                dim hserver as static long
                dim hsock as static long
                dim buffer1 as static string
                dim buffer2 as static string

                select case cbmsg
                case %WM_INITDIALOG
                hserver = freefile
                tcp open server port 2000 as hserver
                tcp notify hserver, accept to cbhndl as %WM_SERVERNOTIFY

                case %WM_SERVERNOTIFY
                select case lowrd(cblparam)
                case %FD_ACCEPT
                hsock = freefile
                tcp accept hserver as hsock
                tcp notify hsock, recv close to cbhndl as %WM_SERVERNOTIFY

                case %FD_CLOSE
                tcp close hsock

                case %FD_READ
                'tcp recv hsock, 2048, buffer2

                do
                tcp recv hsock, 8, buffer1
                buffer2 = (buffer2 & buffer1)
                msgbox buffer2
                loop until buffer1 = ""

                msgbox buffer2

                end select

                end select
                end function

                callback function dobutton() as long
                dim address as long
                dim hsock as long


                host addr to address

                hsock = freefile
                tcp open port 2000 at FormatIP(address) as hsock
                tcp send hsock, "Hello, this is just a test message"
                tcp close hsock
                end function

                function pbmain() as long
                dim hdlg as long

                dialog new %HWND_DESKTOP, "Send", %NULL, %NULL, 256, 96, %DS_CENTER or %WS_CAPTION or %WS_SYSMENU to hdlg
                control add button, hdlg, %IDBUTTON, "start", 4, 4, 32, 14 call dobutton
                dialog show modal hdlg, call dlgproc
                end function

                {/code}

                ------------------

                Comment


                • #9
                  Ok, posting the code didn't work the way I wanted it to...

                  how do post code into this forums like you did Semen ?

                  Cheers !

                  ------------------


                  [This message has been edited by mark smit (edited May 10, 2000).]

                  Comment


                  • #10
                    Mark --
                    1) to post a code you should type
                    [ code ] <--- without spaces
                    Text of program
                    [ /code ] <--- without spaces

                    2) I guess, that you try to rebuild PBCC EchoServ & Eclient.

                    Note, should be TWO programs - server & client, started in the same moment.
                    In your code you try to send a message to yourself. Results you see.
                    Look PBCC samples once again.

                    ------------------

                    Comment


                    • #11
                      Hello Semen !

                      I was trying to write a small file transfer program. The program I just sent you was just to try out an experiment. The original program is much bigger. Just for the fun of it could you please copy the example program and run it and tell me what happens on your machine ? I should also tell you that I'm running Windows 2000 Pro here. I still don't know why my program acts as though it is stuck in the "DO" loop until the connection is closed. This only happens if I try to read the TCP stream in small chunks rather than read as much as possible with one "recv" line.

                      Cheers!

                      ------------------

                      Comment


                      • #12
                        Mark --
                        I tested this fragment under Win2000 Pro.
                        Sometimes I saw Msgbox with some letters, then GPF.
                        Sometimes - imm. GPF.
                        After this I encounted that you send message to yourself.
                        Meanwhile, PBCC samples - server/client - work fine.

                        ------------------

                        Comment


                        • #13
                          Hello again...

                          Well I'm glad to see that it also happend on your machine. I dont think that its my code because if you comment out the do/loop and uncomment out the single line right after %FD_READ then the program works just fine. I have tried the program with and without static string buffers but both versions do the same.

                          Uncomment the line "tcp recv hsock, 2048, buffer2"
                          rem out the "DO WHILE LOOP"

                          and try it, then it works but this code should work either way. In one method I just read in the full buffer and the other I read in small chunks and add them to the main buffer.

                          This really should work! (but it doesn't)
                          I hope lance can have a look at this also...

                          Cheers Semen!

                          ------------------


                          [This message has been edited by mark smit (edited May 10, 2000).]

                          Comment


                          • #14
                            Mark -

                            Just a thought- I noticed that you always read the same number of characters from the stream. In my experience with serial i/o, rarely is the remaining number of characters in the input buffer the same as the rest of the blocks of the incoming data. I have not yet used the TCP calls (have used UDP), but perhaps it is possible that you are reading past the end of the data on the last read. Normally, I test to see how many bytes are in the input buffer prior to performing a read, and if the buffer has fewer bytes than my standard read count, I specify the number that actually exist in the buffer. Hope this helps!

                            Shawn Bever

                            Comment


                            • #15
                              Mark,

                              If the problem has not yet been resolved (see related thread on connecting to ftp.powerbasic.com with TCP), then post the current 'version' of your code and I'll try to take a look.

                              Thanks!

                              ------------------
                              Lance
                              PowerBASIC Support
                              mailto:[email protected][email protected]</A>
                              Lance
                              mailto:[email protected]

                              Comment

                              Working...
                              X