sorry for my bad English.
The Context :
I have 6 variables
- unsigned char
- char
- unsigned short
- int
- int
- int
I serialize this data for prepare the send to socket.
The problem, how can i store my serialized data and send it ?
My first solution, use an structure for send my data but this solution requires a cast and the cast action is very slow.
Have you better solution than store my variable in structure ?
#include <sstream>
#include <string.h>
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#define PORT 4241
template<typename T>
inline std::ostream& raw_write(std::ostream &os, const T &t)
{
return os.write( reinterpret_cast<const char*>(&t), sizeof t);
}
int main()
{
char protocole;
char id_module;
unsigned short id_message;
int id_client;
int size_msg;
unsigned long timestamp;
SOCKET csock;
SOCKADDR_IN csin;
protocole = 1;
id_module = 2;
id_message = 256;
id_client = 8569;
size_msg = 145;
timestamp = 1353793384;
csock = socket(AF_INET, SOCK_STREAM, 0);
csin.sin_addr.s_addr = inet_addr("127.0.0.1");
csin.sin_family = AF_INET;
csin.sin_port = htons(PORT);
connect(csock, (SOCKADDR*)&csin, sizeof(csin));
raw_write(ss, protocole);
raw_write(ss, id_module);
raw_write(ss, id_message);
raw_write(ss, id_client);
send(csock, ss.str().c_str(), strlen(ss.str().c_str()), 0);
close(csock);
}
Doesn’t work because string contain ‘\0’ and send cut it.
I said, cast is slow on many data send. At the receive i need to cast again for recovery my data.
This action is more slow than just bytes reading.
I f you dont want to do it from scratch, you could use Google Protocol Buffers. Its a strong library letting you define a protocol, which is nothing else but a class, that can (de)serialize itself to(from) a stream, file, buffer or string.
I use it myself, its nice to serialze it to a string which is easy to send via socket.
EDIT: Reply to comment:
Okay then notice that its not
send (...)truncating your stream. Its c_str() which ends on a'\0'. Maybe you should try to avoid streams and use a container which offers access to its raw data like std::string or std::vector withconst void * data(). You could pass this andsize()tosend(...).