Pregunta

Tengo un programa de servidor de cliente y donde quiero enviar una estructura entera del cliente y entonces la salida del miembro de estructura "ID" en el servidor.

He hecho todo el etc conectar y ya logrado enviar una cadena a través de:

send(socket, string, string_size, 0);

Por lo tanto, es posible enviar una estructura en lugar de una cadena a través send ()? ¿Puedo reemplazar mi memoria intermedia en el servidor para ser una estructura vacía del mismo tipo e ir?

¿Fue útil?

Solución

... Welll envío de estructuras a través de la red es un poco difícil si usted lo está haciendo correctamente.

Carl es correcto - se puede enviar a una estructura a través de una red diciendo:

send(socket, (char*)my_struct, sizeof(my_struct), 0);

Pero aquí está la cosa:

  • sizeof (my_struct) puede cambiar entre el cliente y el servidor. Los compiladores suelen hacer una cierta cantidad de relleno y alineación, así que a menos que defina explícitamente la alineación (tal vez usando un #pragma pack ()), que el tamaño puede ser diferente.
  • El otro problema tiende a ser de orden de bytes. Algunas máquinas son big-endian y otros están ascendente hacia la izquierda, por lo que la disposición de los bytes pueden ser diferentes. En realidad, a menos que su servidor o cliente se ejecuta en el hardware no es de Intel (que probablemente no es el caso), entonces existe más en la teoría que en la práctica este problema.

Así que la solución la gente a menudo proponen es tener una rutina que serializa la estructura. Es decir, se envía el miembro de datos struct uno a la vez, lo que garantiza que el cliente y el servidor sólo envían () y recv () el número exacto de bytes que se codifican en su programa.

Otros consejos

¿Son las máquinas cliente y servidor "el mismo"? Lo que usted propone sólo funcionará si los compiladores de la C en cada extremo diseñar la estructura en la memoria exactamente lo mismo. Hay un montón de razones por las que esto puede no ser el caso. Por ejemplo los macines cliente y servidor pueden tener diferentes arquitecturas, a continuación, su forma de representar los números en la memoria (big endian, little-endian) puede ser diferente. Incluso si los clientes máquinas y equipo de servidor tienen la misma arquitectura de dos compiladores de C diferentes pueden tener diferentes políticas para la forma en que trazan estructuras en la memoria (por ejemplo. Relleno entre campos enteros para alinear en límites de palabra). Incluso el mismo conmpiler con diferentes banderas podría dar resultados diferentes.

De manera pragmática, supongo que su cliente y el servidor son el mismo tipo de máquina y así lo que usted propone a trabajar, sin embargo es necesario tener en cuenta que, por regla general, no lo hará y por eso estándares como CORBA se inventaron, o por qué la gente utiliza alguna representación general, tales como XML.

Usted puede, si el cliente y el servidor han presentado la estructura de la misma manera, lo que significa que los campos son todos del mismo tamaño, con el mismo relleno. Por ejemplo, si usted tiene un long en su estructura, que podría ser de 32 bits en una máquina y 64bits, por el otro, en cuyo caso no se recibe correctamente la estructura.

En su caso, si el cliente y el servidor siempre van a estar en las implementaciones de C muy similares (por ejemplo, si esto es sólo el código que está utilizando para aprender algunos conceptos básicos, o si por alguna otra razón, usted sabe que su código será sólo tenga que ejecutar en su versión actual de OSX), entonces es probable que pueda salirse con la suya. Sólo recuerde que su código no necesariamente funcionará correctamente en otras plataformas, y que hay más trabajo por hacer antes de que sea adecuado para su uso en la mayoría de situaciones del mundo real.

Para la mayoría de aplicaciones cliente-servidor, esto significa que la respuesta es que no se puede hacer en general. Lo que realmente hace es definir el mensaje en términos del número de bytes enviados, qué orden, lo que significan, y así sucesivamente. A continuación, en cada extremo, se hace algo específico de la plataforma para asegurar que la estructura que está utilizando tiene exactamente el diseño necesario. Aun así, es posible que tenga que hacer algún intercambio de bytes si va a enviar miembros enteros de la estructura ascendente hacia la izquierda, y luego quiere que su código se ejecute en una máquina-big endian. formatos de intercambio de datos como XML, JSON y búferes de protocolo de Google existir de manera que usted no tiene que hacer esto más incómoda.

[Editar: también recordar, por supuesto, que algunos miembros de la estructura no se pueden enviar a través del cable. Por ejemplo, si su estructura tiene un puntero en él, a continuación, la dirección se refiere a la memoria de la máquina de envío, y es inútil en el extremo receptor. Disculpas si esto ya es obvio para usted, pero ciertamente no es evidente para todo el mundo cuando sólo están comenzando con C].

Se puede, pero hay que tener en cuenta 2 cosas importantes.

  1. Los programas en ambos extremos tienen que ser ABI compatibles. Por lo general son Si ambos extremos se ejecutan en la misma arquitectura de procesador, mismo sistema operativo, compilado con las mismas opciones del compilador y del compilador.
  2. TCP es un arroyo. Usted tiene que asegurarse de que está enviando toda la estructura. Mira la documentación de la llamada send () - devuelve el nr de bytes enviados - que podría ser menor que usted le dijo que. Lo mismo en el lado receptor. El hecho de que usted envió la estructura con 1 llamada de envío, no significa que lo recibirá con 1 llamada recv. Pueden transcurrir varias llamadas recv para conseguir todas las piezas.

Sí, estructuras del mismo tipo son todos del mismo tamaño. Si usted recibe su fundición de puntero derecho ya está bueno para ir.

En general, es una mala idea hacer esto, incluso si su cliente y el servidor de llegar a diseñar la estructura en la memoria de la misma manera.

Incluso si usted no tiene intención de pasar estructuras de datos más complejas (que implicaría punteros) de ida y vuelta, recomiendo que serializar los datos antes de enviarlos a través de la red.

Enviar los datos como archivo de texto y decodificar después de recibirlo. Esta es la mejor manera si desea que sus datos como su enviado !!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top