Announcement

Collapse
No announcement yet.

FD_READ and FD_WRITE

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

  • FD_READ and FD_WRITE

    Hello again...

    I dont mean to be such a pest here but I really have no idea were to begin looking for this sort of information. The MSDN doesn't help much because its all geared towards MFC and I can't even find anything on how to use FD_READ and FD_WRITE together.

    I just want to know how FD_WRITE works with FD_READ. I have used FD_READ in some programs and it works great but FD_WRITE only seems to be called once. I was under the impression that the two complimented each other so that you would know when to send the next block of data. If the FD_WRITE notification only gets sent once how can you have constant communication then. I know I could just rely on the FD_READ notification by sending back a reply that would trigger the FD_READ notification on the other side of the connection but thats too much overhead, doesn't TCP already do this and use the FD_RAD and FD_WRITE to notify you?

    I was under the impression that this is how the TCP notification would work. I makes sense to do it this way doesn't it?

    Code:
    client side              server side
    --------------------------------------------
    FD_WRITE: send data  ->  FD_READ:  read data
    FD_WRITE: send data  ->  FD_READ:  read data
    FD_WRITE: send data  ->  FD_READ:  read data
    FD_READ:  read data  <-  FD_WRITE: send data
    FD_WRITE: send data  ->  FD_READ:  read data
    I have tried to write a small example of this but FD_WRITE only gets sent once. I really am stuck here and I just spent over $500 bucks on book that will be here in "6-8 weeks". I would really appreciate any help that could be given. Dont get me wrong here, Im not asking anybody to write a working program for me, maybe just point me in the right direction...(smile)



    -------------
    Cheers

  • #2
    Hi Mark

    could tell me - or better show me what you want to do? How are you listening (accepting) for the connecting socket? Are you using a select loop or a message loop or one of the WSAAsnyc functions?

    And no, you're not a pest

    Florent

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

    Comment


    • #3
      Hello Florent!

      Both the client and server side use...

      Code:
      %WM_SOCKET = %WM_USER
      TCP NOTIFY hsock, SEND RECV CLOSE TO CBHNDL AS %WM_SOCKET
      In there message handler loops they looks like this...

      Code:
      SELECT CASE LOWRD(CBLPARAM)
        CASE %FD_READ
          TCP RECV hsock, 2048, buffer
      
        CASE %FD_WRITE
          TCP SEND hsock, buffer
      
        CASE %FD_CLOSE
          TCP CLOSE hsock
      ENDSELECT
      Well, ok there is alot missing from here but the idea was that each side would have the same message handler and just start communicating. They would both send the same buffer back and forth over and over, but the message only gets sent once on either end and then stops.

      I have just found a REALLY good document on the WinSock API and I would like to share it with every body on the message board, this document explained pretty good why the above was not working.

      Here is the link where I got it.

      homepage: http://freeshell.org/~michael/winsock.html
      document: http://freeshell.org/~michael/files/wsapi22.zip



      ------------------
      Cheers

      Comment


      • #4
        Hi Mark

        using the FD_WRITE notification in this way will not work - you've got a recursive situation - no FD_WRITE will be issued until you send data and you won't send data until you receive an FD_WRITE. So the client issues the first write and you *may* get an FD_WRITE notification IF THE FD_WRITE fails (i.e the send buffer is not large enough or some other such thing)!

        In the case you are presenting there is effetively no "client" side since both apps are de facto "servers". Are you thinking of developing a chat application, or some other form of message driven application?

        Such apps don't fit in the "classic" client/server mode since they are effectively data driven. I think you were trying to get "onSend" ready notification in the CAsync socket class style.

        You could implement this using a small FSM (Finite State Machine) where each state sets a flag telling the app what the next step is - something like:

        (Pseudocode)
        Code:
        SELECT CASE lState
            CASE %READING 
                IF ReceivedEnough THEN
                    lState = %WRITING
                END IF
            CASE %WRITING
                IF AllSent THEN
                    lState = %READING
                END IF
        END SELECT
        This is very simplistic but illustrates the kinf of thing I mean. Let me know what you make out of it.

        Cheers

        Florent



        [This message has been edited by Florent Heyworth (edited May 24, 2000).]

        Comment


        • #5
          Hello Florent!

          What im trying to do is send data from a client computer, over a cell phone internet connection, to my server. The problem is because the connection on the cell phone is so bad, and can drop out at any time, I cant afford to have the client and server constantly talking back and forth for each data packet of only 256bytes. The amount of overhead that would be involved would be better used to send more real data. The big problem im having right now is that the TCP SEND and TCP RECV commands dont seem to work right on my computer. I do have a working client/server program right now but for each packet I send out I have to wait for the server to send a packet back saying "OK" so the next send packet can happen. This is just to much wasted air time, that could potentialy be used to transfer more data.

          TCP SEND should bail out with an error if it can't send anymore data right? well on my machine it doesn't.

          TCP RECV should also bail out if there isnt any data left to read correct? well on my machine both of these functions just sit and hang. I am just about ready to pull out my hair!



          ------------------
          Cheers

          Comment


          • #6
            Hello again...

            Just to give you an idea how bad a cell phone connection to the internet can be out in the bush, It took about 15 tries to establish the connection alone and about 35 minutes to send a 20k data file. That works out to about 9bytes a second. These cell phone data boxes only run at around 2400baud.

            Thats just gross ay!

            ------------------
            Cheers

            Comment


            • #7
              Hi Mark

              since the PB TCP commands encapsulate the Winsock API, the PB engine may just be swallowing the FD_WRITE notification and correcting the error situation. Check WSAGetLastError, ERR and ERRAPI after each send/receive.

              Instead of sending "OK" notifications you *might* be better off sending a header along with your data packet with a sequence (maybe 2 &HFF)+ the expected packet length. That would save a round-trip + enable you to do more "intelligent" error handling.

              Cheers

              Florent

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

              Comment


              • #8
                Hello Again!

                I can check the ERR and ERRAPI all I want but the problem is that the TCP RECV call hangs and does not return. If there isn't any data in the buffer to read and I issue a TCP RECV my program never comes back from calling the function, it just stays inside the TCP RECV call and never exists! thus I can not check the error status of this call. Consiquently the TCP SEND does the same thing, If the buffer is full the TCP SEND call never returns. So the only method I have left to use is, trapping the FD_READ notification on both the client and server side, Initiate one block transfer. This will case a FD_READ notification on the server side. Then the server will send an "OK" message to the client causing the FD_READ notification to trigger and then the client would send a block of data back to the server provided there is data left to transmit!

                I really dont like this method because it makes for too much overhead and waiting. The TCP protocall already has this sort of handshaking built right in so why would I want to reinvent the wheel? (smile)

                Do you know of any way to know ahead of time if the TCP buffer is full or empty?

                I would really like to thank you for having this chat with me. I find it really helps not only myself but the other person as well. Bouncing idea's around is a great way to open up your eyes...

                ------------------
                Cheers

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

                Comment


                • #9
                  mark,
                  Are you using the TIMEOUT parameter on the TCP OPEN?


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

                  Comment


                  • #10
                    Yup! I did make use of the TIMEOUT argument, In fact, I have used numbers from about 500ms to 20000ms. For some reason the timeout never happens...



                    ------------------
                    Cheers

                    Comment


                    • #11
                      Mark

                      The TCP protocall already has this sort of handshaking built right in so why would I want to reinvent the wheel? (smile)
                      Yes at the transport level - not the application level...

                      If I understand you correctly you find yourself having to send an ACK (your "OK" notification) back to initiate the next round of sending, reading. Do you need 2 way communication or just one way (from a computer via cellphone to a server)?

                      Cheers

                      Florent

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

                      Comment


                      • #12
                        Good Morning!

                        Well Florent, Idealy I would like to just tell the server that I am going to send a file in one packet and then follow that up with data packets for that file. The unfortunate thing is that I need to have this two way communication because I need to know if the server can accept more data. I would not have to do this if the TCP SEND function would return an error when the send buffer is full, As it sits right now, If the send buffer becomes full both client and server side hang.

                        If there was some way to find out if there is still room in the send buffer before I call TCP SEND then this would probably fix my problem. On the server side it would be nice to know how much data is waiting in the buffer before a TCP RECV...



                        ------------------
                        Cheers

                        Comment

                        Working...
                        X