Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Tcp/Ip send() does sometimes not succeed

Tcp/Ip send() does sometimes not succeed

Scheduled Pinned Locked Moved C / C++ / MFC
c++sysadminquestioncsharphelp
16 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Mark Salsbery

    florianhaar wrote:

    Frustrating

    Indeed! Which select are you using? Can you post the code you use to receive (it's almost always a problem on the receiving end)? Mark

    D Offline
    D Offline
    Dee Veloper
    wrote on last edited by
    #5

    Thanks for your help so far Mark. I hope this code snippet gives you an idea for a solution: TIMEVAL tv; tv.tv_sec=0; tv.tv_usec=5; FD_ZERO(&clientSet); FD_SET(theClient->sock,&clientSet); if ((errCode=select(0,&clientSet,NULL,NULL,&tv))>0) { if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) { //error handling ... } else message handling... I do not receive an error or a message. Select() returns only timeout. Flo

    M 1 Reply Last reply
    0
    • D Dee Veloper

      Thanks for your help so far Mark. I hope this code snippet gives you an idea for a solution: TIMEVAL tv; tv.tv_sec=0; tv.tv_usec=5; FD_ZERO(&clientSet); FD_SET(theClient->sock,&clientSet); if ((errCode=select(0,&clientSet,NULL,NULL,&tv))>0) { if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) { //error handling ... } else message handling... I do not receive an error or a message. Select() returns only timeout. Flo

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #6

      if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) ... What is maxRead? How are you handling if recvMsgSize < maxRead after the call?

      D 1 Reply Last reply
      0
      • M Mark Salsbery

        if ((recvMsgSize=recv(theClient->sock,addBuffer,maxRead,0))<=0) ... What is maxRead? How are you handling if recvMsgSize < maxRead after the call?

        D Offline
        D Offline
        Dee Veloper
        wrote on last edited by
        #7

        maxRead is the maximum number of bytes the buffer can store. if recvMsgSize is smaller than maxRead (which is normally the case) I copy the data to additional buffers and combine them as soon as all bytes are received. With my problem the data received is always smaller than maxRead.

        M 1 Reply Last reply
        0
        • D Dee Veloper

          Hi! I am currently programming server/client stuff with the c++ functions send and recv. Normally everything works fine but sometimes the client tells me it has sent a message successfully but it is not received by the server. I tracked the packets in the network and no packet had been sent. Documentation says not every successful call to send() guarantees that the data is received by the client. Unfortunately the packet is never sent (waited up to 3 minutes). Since Tcp/Ip is a reliable protocol, I expected the packets to be received by the client as long as the connection is not terminated. How can I make sure that send really sends my data? Is there a flush() command? (using Tcp/Ip non blocking windows socket, checking for send/receive with select). Any help would be greatly appreciated!!! Thx Flo P.S. Before you ask: it has to be c++ send and recv - no MFC or C# stuff...

          E Offline
          E Offline
          Eytukan
          wrote on last edited by
          #8

          If I remember it correctly, If the packet size become too small, very small that it doesnt send it until the successive packets join together to make good "chunk". It's somewhat termed as "Neigile's" Nagle algorithm or so. just check the size of the packets your are sending. -- modified at 13:16 Friday 26th January, 2007


          Code-Frog:So if this is Pumpkinhead. Time for him to run and hide. It's an interesting thought really.

          M 1 Reply Last reply
          0
          • E Eytukan

            If I remember it correctly, If the packet size become too small, very small that it doesnt send it until the successive packets join together to make good "chunk". It's somewhat termed as "Neigile's" Nagle algorithm or so. just check the size of the packets your are sending. -- modified at 13:16 Friday 26th January, 2007


            Code-Frog:So if this is Pumpkinhead. Time for him to run and hide. It's an interesting thought really.

            M Offline
            M Offline
            Mark Salsbery
            wrote on last edited by
            #9

            Nagle :) The data is sent after (by default on Windows Sockets) 200ms though. Mark

            E 1 Reply Last reply
            0
            • M Mark Salsbery

              Nagle :) The data is sent after (by default on Windows Sockets) 200ms though. Mark

              E Offline
              E Offline
              Eytukan
              wrote on last edited by
              #10

              Done. Thanks :-D


              Code-Frog:So if this is Pumpkinhead. Time for him to run and hide. It's an interesting thought really.

              1 Reply Last reply
              0
              • D Dee Veloper

                maxRead is the maximum number of bytes the buffer can store. if recvMsgSize is smaller than maxRead (which is normally the case) I copy the data to additional buffers and combine them as soon as all bytes are received. With my problem the data received is always smaller than maxRead.

                M Offline
                M Offline
                Mark Salsbery
                wrote on last edited by
                #11

                hmmm From what I've seen there shouldn't be a problem. You've debugged the code? Examining network packets isn't necessarily the way to debug since the potocol is free to re-packetize your data as needed. Have you changed any socket options on either end? There's a bug in the code somewhere :) Mark

                D 1 Reply Last reply
                0
                • M Mark Salsbery

                  hmmm From what I've seen there shouldn't be a problem. You've debugged the code? Examining network packets isn't necessarily the way to debug since the potocol is free to re-packetize your data as needed. Have you changed any socket options on either end? There's a bug in the code somewhere :) Mark

                  D Offline
                  D Offline
                  Dee Veloper
                  wrote on last edited by
                  #12

                  I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo

                  M 2 Replies Last reply
                  0
                  • D Dee Veloper

                    I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo

                    M Offline
                    M Offline
                    Mark Salsbery
                    wrote on last edited by
                    #13

                    :) If you'd like to post the send-side code I'd be happy to look at it as well. Mark

                    M 1 Reply Last reply
                    0
                    • M Mark Salsbery

                      :) If you'd like to post the send-side code I'd be happy to look at it as well. Mark

                      M Offline
                      M Offline
                      Mike ONeill
                      wrote on last edited by
                      #14

                      I generally agree with Mark's observation that problems like this are almost always caused by code on the receiving side. Here, you have set the timeout for select() to 5 microseconds. That's way too short. Your understanding of the send() function is slightly wrong. send() does not actually send bytes out over the wire; that happens later when the winsock TCP stack determines that it's time to send data on the wire, after considertion of things like Nagle, delayed ACK etc. Rather, a successful call to send() only indicates that the winsock stack has successfully transferred data in your user buffer to its internal winsock buffer. The return value from send() tells you exactly how much of your buffer has been accepted; you should therefore inspect the returned value to ensure that winsock transferred everything to its internal buffer. So, if you are debugging and single-stepping through your code, and you see a successful completion of the call to send(), then it's probably still too early for a sniffer to see the actual data on the wire. That will happen, but it will happen at some indeterminate time in the future. Mike

                      M 1 Reply Last reply
                      0
                      • M Mike ONeill

                        I generally agree with Mark's observation that problems like this are almost always caused by code on the receiving side. Here, you have set the timeout for select() to 5 microseconds. That's way too short. Your understanding of the send() function is slightly wrong. send() does not actually send bytes out over the wire; that happens later when the winsock TCP stack determines that it's time to send data on the wire, after considertion of things like Nagle, delayed ACK etc. Rather, a successful call to send() only indicates that the winsock stack has successfully transferred data in your user buffer to its internal winsock buffer. The return value from send() tells you exactly how much of your buffer has been accepted; you should therefore inspect the returned value to ensure that winsock transferred everything to its internal buffer. So, if you are debugging and single-stepping through your code, and you see a successful completion of the call to send(), then it's probably still too early for a sniffer to see the actual data on the wire. That will happen, but it will happen at some indeterminate time in the future. Mike

                        M Offline
                        M Offline
                        Mark Salsbery
                        wrote on last edited by
                        #15

                        Thanks Mike! Maybe you meant to post this to the OP :) For some reason I assumed his code was in a loop. If it's not then that 5microsecond timeout is definitely not going to work (well, rarely). Mark

                        1 Reply Last reply
                        0
                        • D Dee Veloper

                          I guess I have to think through my code step by step once again. At least I know now, that send() should send after 200ms as long as the connection is established. Thanks again for your help! Flo

                          M Offline
                          M Offline
                          Mark Salsbery
                          wrote on last edited by
                          #16

                          Hi Flo, Check out Mike O'Neill's reply above. I asked previously how you're handling it when you don't receive the number of bytes requested. Are you looping until you get the bytes you're expecting or just trying to recv once after the 5microsecond wait? Mark

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups