简体   繁体   中英

receive from unix local socket and buffer size

I'm having a problem with unix local sockets. While reading a message that's longer than my temp buffer size, the request takes too long (maybe indefinitely).

Added after some tests: there is still problem with freeze at ::recv. when I send (1023*8) bytes or less to the UNIX socket - all ok, but when sended more than (1023*9) - i get freeze on recv command. maybe its FreeBSD default UNIX socket limit or C++ default socket settings? Who know?


i made some additational tests and I am 100% sure that its "freeze" on the last 9th itteration when executing ::recv command, when trying to read message >= (1023*9) bytes long. (first 8th itterationg going well.)

What I'm doing: The idea is to read in a do/while loop from a socket with

::recv (current_socket, buf, 1024, 0);

and check buf for a SPECIAL SYMBOL. If not found:

  1. merge content of buffer to stringxxx += buf;
  2. bzero temp buf
  3. continue the ::recv loop

How do I fix the issue with the request taking too long in the while loop?

Is there a better way to clear the buffer? Currently, it's:

 char buf [1025];
 bzero(buf, 1025);

But I know bzero is deprecated in the new c++ standard.

EDIT: * "Why need to clean the buffer *

I see questions at comments with this question. Without buffer cleanup on the next(last) itteration of reading to the buffer, it will contain the "tail" of first part of the message.

Example:

 // message at the socket is "AAAAAACDE"
 char buf [6];
 ::recv (current_socket, buf, 6, 0); // read 6 symbols, buf = "AAAAAA"
 // no cleanup, read the last part of the message with recv
 ::recv (current_socket, buf, 6, 0); 
 // read 6 symbols, but buffer contain only 3 not readed before symbols, therefore
 // buf now contain "CDEAAA" (not correct, we waiting for CDE only)

除了bzero ,您可以使用

memset(buf, 0, 1025);

These are 2 separate issues. The long time is probably some infinite loop due to a bug in your code and has nothing to do with the way you clear your buffer. As a matter of fact you shouldn't need to clear the buffer; receive returns the number of bytes read, so you can scan the buffer for your SPECIAL_SYMBOL up to that point.

If you paste the code maybe I can help. more.

Just to clarify: bzero is not deprecated in C++ 11. Rather, it's never been part of any C or C++ standard. C started out with memset 20+ years ago. For C++, you might consider using std::fill_n instead (or just using std::vector , which can zero-fill automatically). Then again, I'm not sure there's a good reason to zero-fill the buffer in this case at all.

When your recv() enters an infinite loop, this probably means that it's not making any progress whatsoever on the iterations (ie, you're always getting a short read of zero size immediately, so your loop never exits, because you're not getting any data). For stream sockets, a recv() of zero size means that the remote end has disconnected (it's something like read() ing from a file when the input is positioned at EOF also gets you zero bytes), or at least that it has shut down the sending channel (that's for TCP specifically).

Check whether your PHP script is actually sending the amount of data you claim it sends.

To add a small (non-sensical) example for properly using recv() in a loop:

char buf[1024];
std::string data;
while( data.size() < 10000 ) { // what you wish to receive
    ::ssize_t rcvd = ::recv(fd, buf, sizeof(buf), 0);
    if( rcvd < 0 ) {
        std::cout << "Failed to receive\n";  // Receive failed - something broke, see errno.
        std::abort();
    } else if( !rcvd ) {
        break; // No data to receive, remote end closed connection, so quit.
    } else {
        data.append(buf, rcvd); // Received into buffer, attach to data buffer.
    }
}

if( data.size() < 10000 ) {
    std::cout << "Short receive, sender broken\n";
    std::abort();
}

// Do something with the buffer data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM