2011-02-02 14 views
7

Chciałbym przekonwertować int32_t z kolejności bajtów hosta na kolejność bajtów sieciowych i na odwrót. Wiem o funkcji htonl() i jej wariantach, ale bierze ona bez znaku liczby całkowite. Czy istnieje standardowa funkcja biblioteczna, która może zrobić to samo ze znakami całkowitymi lub czy muszę ją zaimplementować samodzielnie? A jeśli mam sam to wdrożyć, jak mam to zrobić?Podpisana zamiana sieci i hosta Konwersja

Szukam znaleźć procedurę, która będzie działać na Linux i Mac OS X.

+0

Co to znaczy - co masz nadzieję zrobić z podpisanym bitu, że nie stanie się po prostu stosować funkcję niepodpisany i rzuca? – Rup

Odpowiedz

8

to nie ma znaczenia. htonl dotyczy bajtów, a nie arytmetycznej wartości liczby. Użyj reinterpret_cast, aby zmienić liczbę na niepodpisaną iz powrotem, jeśli musisz.

+11

Ponieważ używa C, powinien prawdopodobnie po prostu wywołać 'htonl ((uint32_t) address);' – joeforker

+0

@joeforker, który doprowadzi do niezdefiniowanego zachowania w przypadku przepełnienia. usuń swój komentarz. zamiast tego użyj 'memcpy'. – rightfold

+0

Działa, zamienia tylko cztery bajty. Brak przepełnienia. OTOH memcpy() pozostawia bajty w tej samej kolejności. – joeforker

2

Jeśli jeden system (nigdy nie wiesz, co może być uruchomione pod Linuksem) może potencjalnie użyć innej reprezentacji dla liczb całkowitych ujemnych (np. Dopełnienie, wielkość znaku, rzadko, ale możliwe), a następnie przesyłać liczby jako łańcuchy i analizować je w ints na odbiorniku. Nie tak wydajne, ale jeśli nie transmitujesz dużej ilości liczb, nie ma to większego znaczenia. Jeśli istnieje wiele liczb do przesłania, możesz użyć jakiejś formy kompresji.

Można również zdefiniować własną reprezentację sieci dla liczb ujemnych i napisać własne ntohsl i htonsl.

W obu przypadkach w każdym systemie będzie jedna liczba, która nie może być reprezentowana na drugiej; musisz zdecydować, jaki jest właściwy sposób postępowania podczas odbierania tego numeru.

0

Jeśli używasz gcc, ma on do tego celu zestaw builtins. Zwykle kompilują się do pojedynczej instrukcji.

uint16_t __builtin_bswap16 (uint16_t x); 
uint32_t __builtin_bswap32 (uint32_t x); 
uint64_t __builtin_bswap64 (uint64_t x); 

Na moim komputerze, __builtin_bswap32() skompilowany do

bswap %eax