|
Hi Brad, > Sometimes when I send a request, I get a response, but not > all of it... That's the way stream sockets work. Expected behavior and all that... You see, when you create a socket wtih SOCK_STREAM, you're telling the system that it's a stream socket. The data written to the socket is a stream of bytes without any type of "record" or "line" or any other type of boundaries in it. Just an ongoing stream of bytes. For example, if you write the string "Have a nice day" to the socket, all it knows is that these bytes make up part of the stream. It does not know that the "have a nice day" is supposed to be a "single response" or "record" or "line" or whatever. For all it knows, you'll be adding more data to the end of that string in a successive call, or that this string is part of a previous response that you sent it. Again, it knows nothing except that it's a stream. Likewise, when you call read() or recv(), it will read one or more bytes. It does not know that you want to receive "have a nice day", all it knows is that you want to receive something. It has no clue how much data there is to receive, etc. Whatever is in the socket's read buffer at that moment gets returned to your prgoram. It's entirely possible that you'll read "Hav" the first time, then "e a n" the second time, then "ice day" the third time. And it's possible that you'll start receiving part of the next response after that in the 4th call... the socket, again, has no idea that it was supposed to be a particular string that's a particular length. You must write your applications so that they understand this. They should call the recv() or read() API in a loop until they get all of the data that they intend to receive. If you're using non-blocking sockets, the same is true when calling send() or write(). It's very possible that these APIs will only send part of your data. You'll have to check the length sent, and send anything else in a subsequent call. Though, with blocking sockets, these APIs do wait until it's all loaded into the write buffer. The read/recv() APIs, by contrast, only wait until there's SOMETHING to read. As soon as at least one byte is in the read buffer, it returns the data to your program. The length that you pass in the 3rd parameter to these APIs is only telling the API how much memory you've provided to read into -- it does NOT tell the API how many bytes it's expected to read. You mentioned something about the select() API. That won't help you. Select() waits until there's at least one byte available to read, or at least one byte of space available in the write buffer. It does not wait until a particular amount of data is received -- it's no different than recv() on a blocking socket, except that you can specify a timeout and multiple sockets with select(). Oh yeah, I almost forgot because I don't use this option: There's an option that you can use on the the recv() API called MSG_WAITALL that tells the socket to wait until the buffer is full when receiving. However, this causes the socket to block without a timeout, and therefore I don't use it. I prefer to use a loop.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.