2011-03-28 15 views
5

He leído la introducción a la programación de redes de BG, pero un tema sigue siendo cuestionable: encapsulación de datos.
Básicamente, creo una estructura que contiene datos de longitud y un mensaje. Por ejemplo:Encapsulación de datos (programación en red)

struct Data 
{ 
    int length; 
    std::string message; 
} 

¿Cómo puedo enviarlo? Con la función send(), solo puedo enviar variables de tipo * char.
Además, cuando lo envío, en el lado del servidor, ¿debo crear un búfer dinámico de longitud especificado por la encapsulación y empaquetar el mensaje en él?

+1

El tema que está tropezando es "serialización", no encapsulación. – tenfour

+0

+1 Curioso sobre cómo hacer esto de la manera C++. También debería preguntar si debe preocuparse por los problemas endian. – Jeff

Respuesta

2

El enfoque común en C++ es proporcionar funciones que pueden serializar su tipo personalizado en un objeto 'stream', y luego proporcionar una manera de obtener un puntero al inicio del bloque de datos que se acumuló en la secuencia.

Un ejemplo sencillo de esto es std :: ostringstream que se puede utilizar para serializar los datos en una corriente y luego obtener un puntero a la cadena construida:

int i = 13; 
std::string message = "Hi"; 
std::ostringstream stream; 
stream << i << message; 

cout << stream.str() << endl; // prints "13Hi"; 

Se podría hacer lo mismo para su tipo Data proporcionando sobrecargas apropiadas del operador << y >>, como en:

std::ostringstream &operator<<(std::ostringstream &stream, const Data &v) { 
    return stream << v.length << v.message; 
} 

std::ostringstream &operator>>(std::ostringstream &stream, Data &v) { 
    return stream >> v.length; >> v.message; 
} 

el uso de estas funciones, usted puede hacer esto:

Data myData = { 13, "Hello" }; 

std::ostringstream stream; 
stream << myData; 

const std::string serializedData = stream.str(); 
send(.., serializedData.c_str(), serializedData.size() + 1, ..); 

del tamaño de recepción, se puede leer los datos en un búfer y luego usar un objeto std::istringstream para extraer los datos de nuevo:

const char receivedData[ 1024 ]; 
// fill receivedData array using recv() 

std::string s = receivedData; 
std::istringstream stream(s); 
Data myData; 
stream >> myData; 

Es posible que necesite para amortiguar los datos recibidos un poco hasta que la lectura de la corriente tiene éxito.

+0

Estoy un poco confundido. 'myData' tiene un método' c_str() ' – Jeff

+0

@Jeff: Lo siento, olvidé extraer el objeto 'std :: string' de la transmisión. Acabo de arreglar el ejemplo. –

+0

+1 tiene sentido ahora. ¡Gracias! – Jeff

0

Enviar() toma un carácter * para permitir el envío de datos binarios en múltiplos de un byte. ¿Has intentado lanzar a un char *?

En el extremo de recepción, entonces tiene que descomprimir los primeros bytes para descubrir la longitud. Por supuesto, este enfoque supone que el emisor y el receptor utilizan la misma longitud de entrada. También debería tener cuidado con los argumentos de empaque que envía al compilador.

Cuestiones relacionadas