I'm having some issues using write and read functions to interact with a FIFO file, for some reason, when I read the FIFO, I get junk in the readed object (I'm making a minitwitter, so using client-server model):
Client-side:
Breakpoint 1, main (argc=3, argv=0x7fffffffdf88) at Cliente.cpp:50
50 if(write (fdReceiverPipe, registerMessage, sizeof (*registerMessage)) == -1){
(gdb) p registerMessage
$3 = (Mensaje *) 0x605030
(gdb) p *registerMessage
$4 = {sender = 1, mensaje = "21870", tipoRequest = 0}
Server-side:
Breakpoint 1, MessagePipeHandler (
messageRequestCounter=0x606324 <messageRequestCounter>) at Gestor.cpp:166
166 int statusMessagePipe = read (fdMessagePipe, mensaje, sizeof *mensaje);
(gdb) p sizeof (mensaje)
$1 = 8
(gdb) p sizeof (*mensaje)
$2 = 24
(gdb) p *mensaje
$3 = {sender = -144108792, mensaje = "", tipoRequest = 6320304}
For avoiding junk entering the pipe, the client-to-server pipe O_NONBLOCK option is clear and the server-to-client pipe is readed when the server sends a signal, here is the code:
Server-side:
//Function for pipe for messages check and processing
void MessagePipeHandler (int *messageRequestCounter) {
//Open the message pipe
std :: cout << "Abriendo pipe " << mainPipeName << std :: endl;
int fdMessagePipe = open (mainPipeName, O_RDONLY);
if (fdMessagePipe == -1) {
std :: cout << "No se pudo abrir el pipe para los mensaje, ¿Existe el archivo del pipe?" << std :: endl;
exit (EXIT_FAILURE);
} else {
//Activate message pipe service
std :: cout << "¡Servicio de pipe de mensajes online!" << std :: endl;
int statusMessagePipe;
while (true) {
Mensaje *mensaje = new Mensaje ();
int statusMessagePipe = read (fdMessagePipe, mensaje, sizeof (*mensaje));
if (statusMessagePipe == -1) {
std :: cout << "Error al leer el archivo de pipe..." << std :: endl;
exit (EXIT_FAILURE);
} else if (statusMessagePipe > 0) {
//Check message type
switch (mensaje -> getTipoRequest ()) {
//Connection request
case 0:
IDMessageHandler (mensaje);
break;
//Follow
case 1:
server -> setRelation (mensaje -> getSender (), atoi (mensaje -> getMensaje().c_str()), '1');
break;
//Unfollow
case 2:
server -> setRelation (mensaje -> getSender (), atoi (mensaje -> getMensaje().c_str()), '0');
break;
//Tweet
case 3:
DispatchTweet (mensaje);
break;
//Disconnect
case 5:
server -> Disconnect (mensaje -> getSender ());
break;
//Bad request
default:
std :: cout << "El tipo de request es desconocido, continuando..." << std :: endl;
break;
}
(*messageRequestCounter) ++;
}
mensaje -> Dispose ();
}
}
}
Client-side:
int main (int argc, char** argv){
//Installing signal handler
signal (SIGUSR1, (sighandler_t) signalHandler);
//See if IDPipe is created
receiverPipe = argv[2];
int fdReceiverPipe = open (receiverPipe, O_WRONLY);
std :: cout << fdReceiverPipe << std :: endl;
if (fdReceiverPipe > 0) std :: cout << "Pipe de IDs encontrado, registrandose..." << std :: endl;
else {
std :: cout << "No se ha encontrado el pipe, ¿esta encendido el servidor?" << std :: endl;
exit (EXIT_FAILURE);
}
//Register the IDs on the pipe
Mensaje *registerMessage = new Mensaje ();
std :: ostringstream itos;
itos << getpid ();
registerMessage -> setSender (atoi (argv[1]));
registerMessage -> setMensaje (itos.str ());
registerMessage -> setTipoRequest (0);
if(write (fdReceiverPipe, registerMessage, sizeof (*registerMessage)) == -1){
std :: cout << "Se ha presentado un problema al registrar el cliente." << std :: endl;
exit (EXIT_FAILURE);
} else std :: cout << "¡Se ha registrado el cliente con exito!" << std :: endl;
//Set client info and see server mode
pause ();
cliente -> setId (atoi (argv [1]));
cliente -> setPid (getpid ());
std :: cout << "Recibida respuesta, obteniendo configuracion del servidor..." << std :: endl;
Mensaje *serverMessage = new Mensaje ();
std :: string senderPipe ("SenderPipe");
std :: string userId (argv [1]);
senderPipe += userId;
int fdSenderPipe = open (senderPipe.c_str (), O_RDONLY | O_NONBLOCK);
if (fdSenderPipe == -1) {
std :: cout << "No se logro acceder a la configuracion del servidor, ¿esta encendido el servidor?" << std :: endl;
exit (EXIT_FAILURE);
} else {
std :: cout << "Tomando datos del pipe canal, un momento..." << std :: endl;
for (int tries = 0; tries < MAX_TRIES; tries ++) {
int pipeState = read (fdSenderPipe, serverMessage, sizeof *serverMessage);
if (pipeState == -1) {
std :: cout << "No hay configuracion del servidor, reintentando..." << std :: endl;
sleep (2000);
} else {
if(serverMessage -> getMensaje () == "async") {
std :: cout << "Configuracion completada." << std :: endl;
Pause();
break;
} else {
serverModeAsync = false;
std :: cout << "Configuracion completada." << std :: endl;
Pause();
break;
}
}
}
}
std :: cout << "Llamando al menu..." << std :: endl;
Menu ();
}
I have two questions: 1) Is it possible to use write () and read () for object I/O operations in binary files? 2) If not, is there any workaround so I may maintain the OOP I'm using?
Thanks in advance.
EDIT:
Message class:
#ifndef __Mensaje__HXX__
#define __Mensaje__HXX__
#include<iostream>
class Mensaje{
public:
Mensaje();
~Mensaje();
int getSender();
void setSender(int sender);
std :: string getMensaje();
void setMensaje(std::string msg);
int getTipoRequest();
void setTipoRequest(int tipoRequest);
void Dispose ();
private:
int sender;
std :: string mensaje;
int tipoRequest;
};
#include "Mensaje.cxx"
#endif