Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send an std::vector<std::string> over a UNIX socket?

Tags:

c++

unix

sockets

For my application, I need to be able to send an std::vector<std::string> over a UNIX socket(local), and get a copy of the vector on the other end of the socket. What's the easiest way to do this with O(1) messages relative to the size of the vector(i.e. without sending a message for each string in the vector)?

Since this is all on the same host, and because I control both ends of the socket, I'm not concerned with machine-specific issues such as endinness or vector/string representation.

I'd like to avoid using any external libraries for a variety of reasons.

like image 830
Mike Avatar asked Dec 03 '22 12:12

Mike


1 Answers

std::string does not prevent you from having nuls inside your string. It's only when you try to use these with nul sensitive APIs that you run into trouble. I suspect you would have serialize the array by prepending the size of the array and then the the length of each string on the wire.

...
long length = htonl( vec.size() );
write( socket, &length, sizeof(length) );
for ( int i = 0; i < vec.size(); ++i ) {
    length = htonl( vec[i].length() );
    write( socket, &length, sizeof(length) );
    write( socket, vec[i].data(), vec[i].length() );
}
...

Unpacking is done similarly:

...
std::vector vectorRead;
long size = 0;
read( socket, &size, sizeof( size ) );
size = ntohl( size );
for ( int i = 0; i < size; ++i ) {
    std::string stringRead;
    long length = 0;
    read( socket, &length, sizeof( length ) );
    length = ntohl( length );
    while ( 0 < length ) {
        char buffer[1024];
        int cread;
        cread = read( socket, buffer, min( sizeof( buffer ), length ) );
        stringRead.append( buffer, cread );
        length -= cread;
    }
    vectorRead.push_back( stringRead );
}
...
like image 93
David Smith Avatar answered Dec 25 '22 04:12

David Smith