pinkFloyd Δημοσ. 21 Δεκεμβρίου 2008 Δημοσ. 21 Δεκεμβρίου 2008 Καλημέρα Προσπαθώ από έναν client γραμμένο σε C++ να συνδεθώ σε server γραμμένο σε Java με sockets [sockfd = socket(AF_INET, SOCK_STREAM, 0); Για την ακρίβεια] Η σύνδεση γίνεται κανονικά. Το πρόβλημα είναι όταν προσπαθώ να στείλω κάποιον ακέραιο, ο οποίος θα διαβάστεί στον server με την readInt() της κλάσης DataInputStream. Η συνάρτηση διαβάζει 4 byte και επιστρέφει έναν ακέραιο. Πώς μπορώ να μετατρέψω έναν int σε 4 byte στην C++? Δοκίμασα την συνάρτηση που ακολουθεί. Για να στείλω τον ακέραιο από το socket χρησιμοποιώ την write() όπως φαίνεται παρακάτω ( δοκίμασα και την send() ) const char* int2char(int a) { ostringstream os; os << a; string s = os.str(); return s.c_str(); } int a = 5; char* str = int2char( a ); write( sockfd,str,sizeof(str) ); Η τιμή που διαβάζεται στον server, δεν έχει καμία σχέση με αυτή που στέλνει ο client.. (για το παράδειγμα a=5 ο server διαβάζει 889192960). Στο 3ο όρισμα της write() δοκίμασα να βάλω και sizeof(int) ή απλά 4 αλλά το αποτέλεσμα δεν άλλαξε. Πώς μπορώ να το διορθώσω; Καμιά ιδέα; Ευχαριστώ
Directx Δημοσ. 21 Δεκεμβρίου 2008 Δημοσ. 21 Δεκεμβρίου 2008 Το πρόβλημα σου μάλλον έχει σχέση με τον τρόπου που αποθηκεύονται οι αριθμοί στην Java (και σε CPU όπως της Motorola -MC68000 κτλ), η οποία χρησιμοποιεί την μορφή Big Endian (πχ. ένα int -> long 5 = 00000005), και στους επεξεργαστές Intel 80x86 που χρησιμοποιούν την μορφή Little Endian (πχ. ένα long 5 = 05000000). Τα network protocols χρησιμοποιούν επίσης από ότι είδα Big Endian, οπότε από ότι φαίνεται θα πρέπει να κάνεις την απαραίτητη μετατροπή από Little Endian © σε Big Endian (Java). Για την μετάδοση / μετατροπή των στοιχείων στο δίκτυο είδα ότι το υπάρχει η εντολή htonl (τόσο σε Windows API όσο και σε άλλα network APIs). Για περισσότερες πληροφορίες σχετικά με το ζήτημα: http://en.wikipedia.org/wiki/Endianness#Little-endian http://stackoverflow.com/questions/362384/are-integers-in-java-little-endian-or-big-endian http://mindprod.com/jgloss/endian.html http://msdn.microsoft.com/en-us/library/ms738556(VS.85).aspx Γενικά μια αναζήτηση στο Google για Big Endian - Little Endian - Java - Network μπορεί να βοηθήσει. Καλή τύχη!
fromaz Δημοσ. 21 Δεκεμβρίου 2008 Δημοσ. 21 Δεκεμβρίου 2008 Ορθά τα όσα λέει ο DirectX, και σίγουρα θα πρέπει να φτιάξεις τον κώδικά σου έτσι ώστε να είναι endiannes aware. Σε κάθε περίπτωση, όμως, θα πρέπει να στείλεις σωστά τον int, δηλαδη σαν int (LE ή BE ανάλογα την περίπτωση), γιατί αυτό περιμένει η readInt() απέναντι: write(sockfd, &a, sizeof(int));
pinkFloyd Δημοσ. 21 Δεκεμβρίου 2008 Μέλος Δημοσ. 21 Δεκεμβρίου 2008 Ευχαριστώ πολύ για τις απαντήσεις. Θα δοκιμάσω το βραδυ που θα έχω χρόνο και θα επιστρέψω με τα αποτελέσματα -----Προστέθηκε 21/12/2008 στις 11 : 16 : 34----- Τελικά είχατε δίκιο! Χρησιμοποιώντας την συνάρτηση int INT_little_endian_TO_big_endian(int i) { return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff); } δεν χρειάζεται καν να μετατρέψω σε char* τον int, απλά τον στέλνω με την write. Ευχαριστώ πολύ για την βοήθεια
Επισκέπτης Δημοσ. 24 Δεκεμβρίου 2008 Δημοσ. 24 Δεκεμβρίου 2008 Λογικά στην περίπτωση που αποστέλλονται char [] δεδομένα από τον client δεν πρέπει να επηρεάζει το endianess, εφόσον φυσικά ο server δέχεται τα char arrays και κάνει τις απαραίτητες μετατροπές ( (new Integer(s)).intValue() ). Μετατροπές σε Network byte order (big endian) χρειάζονται μόνο όταν πρέπει να στείλουμε int, float κτλ. σε binary μορφή http://beej.us/guide/bgnet/output/html/multipage/advanced.html#serialization
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.