0

I have a client TCP socket that writes a few bytes every five seconds, the server echoes the bytes right back.

Connect() and write() work just fine, and I have a callback at the IP layer that notifies me of the server's echo. This reliably happens between sends.

But I'm having trouble reading the echo from the socket.

I tried using select() to notify me of the incoming echo. Strangely, my callback wasn't invoked until I closed the socket, at which point it was called continuously. For each of these calls, however, read() returned -1/WOULD_BLOCK.

My second approach calls read() asynchronously when the IP layer notifies me of the incoming data. Similarly, read() only returns -1/WOULD_BLOCK. I realize the read() could beat the data to the socket layer, but hopefully it would just mean more to read after the next write.

I'm inclined to think I'm somehow misusing the API since I'm an IP/sockets noob and the select approach behaved so strangely.

It's unlikely a dumb bug since the nearly identical code path works perfectly for UDP mode. The only differences: for UDP I use DATAGRAM mode, sendto(), and recvfrom(). For TCP I use STREAM mode, write(), and read().

mr_dude
  • 107
  • 1
  • 8
  • 1
    when you call read(), what value of count are you providing? – TJD Nov 23 '11 at 23:56
  • Please show your actual reading code. You are clearly using the API wrong. My guess is you are misusing the `SOCKET` handles. – Remy Lebeau Nov 24 '11 at 02:46
  • @TJD: By 'count' you mean number of bytes? I allocate and ask for up to 4k. The same code works for UDP recv(), of course for UDP I pass the additional fromaddr parameter. – mr_dude Nov 28 '11 at 17:43
  • @mr_dude, yes that's what I meant. The standard read() declaration names the parameter count. ssize_t read(int fd, void *buf, size_t count); – TJD Nov 28 '11 at 17:45
  • @Remy: The code is on an offline network, if I'm using the api incorrectly presumably my description of its (mis)use is sufficient. I'm not sure how I could misuse the socket handle, if I pass an invalid sockfd (zero, wrong protocol, etc.) read() will tell me so. – mr_dude Nov 28 '11 at 17:58
  • @TJD: Yep, the implementation I'm using is pretty much the same (+errno). Fd is valid, buf is non-null, and count is positive. I'm going to try to find out if the packet drop counter is going up... – mr_dude Nov 28 '11 at 19:33
  • @mr_dude: without seeing your actual code, there is no way to know if you are using the API correctly or not. If your description alone were sufficient, I wouldn't have to ask to see the code. – Remy Lebeau Nov 28 '11 at 23:11
  • @Remy: While i understand that code helps, it's certainly possible to diagnose the misuse of an API without source. Trivial examples would be if I wasn't calling connect() or didn't understand blocking. Thanks though. – mr_dude Nov 29 '11 at 00:59

1 Answers1

-1

It appears the server was in a state where the TCP echo application had crashed, but UDP echo was fine and the TCP layer was still capable of handling traffic.

So my app would get notification from IP of incoming TCP and believe there was an echo to be read, but find no data at the socket layer. I expected this meant a problem with my use of the API or the layers between IP and sockets. Nope, the notification was for the server ACK rather than the echo, and since that is handled at the TCP layer, it never made it to the socket.

mr_dude
  • 107
  • 1
  • 8
  • That doesn't make any sense whatsoever. If TCP echo was down how could there be incoming TCP data? And you don't get select() events on ACKs. Undoubtedly you were using the API wrong, but without seeing code it's impossible to comment further. – user207421 Mar 18 '12 at 22:40
  • The sever side TCP layer was handling the messaging but the client application had crashed so there was no data. From the IP layer, the incoming data was just TCP messaging. – mr_dude Jul 12 '12 at 17:47
  • Also you could probably improve you tone just a smidge. – mr_dude Jul 12 '12 at 17:47