[so] Case study - Optiunea -fpack-struct

Stefan Bucur stefan.bucur at gmail.com
Sun Dec 9 23:39:07 EET 2007


>
> Nu e o idee buna sa trimiti structuri pe socket.
> Recipientul s-ar putea sa nu fie compilat cu aceleasi flaguri, si daca
> e compilat cu aceleasi flaguri s-ar putea sa aiba alte dimensiuni
> pentru tipurile de date din structura.

Inteleg problema, insa mai intai am definit protocolul, si apoi am
construit o structura C care sa modeleze datele respective pentru
orice fel de arhitectura, folosind tipuri de date din stdint.h:
uint8_t, uint16_t, etc, independente de platforma.

> de ex. esti pe un sistem x64 si ai doua binare, unul de 32 de biti si
> unul de 64 de biti. Ambele compilate cu aceleasi flaguri s-ar putea sa
> aiba dimensiuni diferite pentru int, long etc.

Not the case (see above).

> definind _FILE_OFFSET_BITS=32 sau _FILE_OFFSET_BITS=64 anumite tipuri
> de date (ino_t, off_t ș.a.) pot avea 32, respectiv 64 de biți.
> Daca masina pe care asculta recipientul are o alta arhitectura e
> posibil ca endiannessul sa fie diferit (si poate si dimensiunile).

Endianess-ul este tot timpul network byte order, asa am decis eu; imi
sunt prietene functiile hton* si ntoh* :) [ In general e bine sa fie
asa, de exemplu se pot scrie foarte usor aplicatii Java care sa
suporte protocolul, pentru ca serializeaza si deserializeaza nativ in
NBO).

Iar legat de dimensiunea offset-ilor, se poate rezolva foarte usor
printr-un cast la o dimensiune standard a datelor. Eu iau conventional
32 de biti, si aceasta valoare ramane acceeasi independent de
arhitectura pe care ruleaza serverul (n-ar trebui ca clientul sa faca
niste asumptii legate de arhitectura pe care ruleaza serverul, nu?).

> Aceleasi flaguri pot avea comportamente diferite pe versiuni diferite
> de gcc, etc. you should get the point by now. DON'T DO IT!!!11ONE



>
> In schimb fa o functie de serializare/deserializare a structurii, care
> trimite in o ordine data (pe care o specifici in mod explicit in
> protocol) si una de deserializare.
> In protocol iti specifici in mod explicit: endianness, dimensiune
> campuri, ordine campuri.
>

Aceasta varianta mi se pare foarte potrivita pentru o abordare
sincrona a temei, in care citesti rand pe rand campuri intr-un thread
separat si nu te mai preocupa starea blocanta a socketilor. Dar cum eu
trebuie sa multiplexez non-blocant mai multe request-uri in paralel,
mi se pare mai potrivit (comod) sa citesc un calup omogen mare de date
(adica o structura intreaga), in mod repetat intr-o functie while care
nu tine cont de continutul lor (tinand cont de EAGAIN & stuff), si
apoi sa le interpretez camp cu camp. Profit de organizarea
determinista a campurilor intr-o structura packed; intr-un fel, se
poate spune ca organizez datele intr-o forma foarte usor serializabila
(practic am control total asupra formei binare a datelor, lucru la
care de altfel se refera si serializarea).

Stefan Bucur


More information about the so mailing list