Προς το περιεχόμενο

C++ client Java Server


pinkFloyd

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλημέρα

 

Προσπαθώ από έναν 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 αλλά το αποτέλεσμα δεν άλλαξε.

 

Πώς μπορώ να το διορθώσω; Καμιά ιδέα;

 

Ευχαριστώ

Δημοσ.

Το πρόβλημα σου μάλλον έχει σχέση με τον τρόπου που αποθηκεύονται οι αριθμοί στην 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 μπορεί να βοηθήσει.

 

Καλή τύχη!

Δημοσ.

Ορθά τα όσα λέει ο DirectX, και σίγουρα θα πρέπει να φτιάξεις τον κώδικά σου έτσι ώστε να είναι endiannes aware.

 

Σε κάθε περίπτωση, όμως, θα πρέπει να στείλεις σωστά τον int, δηλαδη σαν int (LE ή BE ανάλογα την περίπτωση), γιατί αυτό περιμένει η readInt() απέναντι:

 

write(sockfd, &a, sizeof(int));

Δημοσ.

Ευχαριστώ πολύ για τις απαντήσεις. Θα δοκιμάσω το βραδυ που θα έχω χρόνο και θα επιστρέψω με τα αποτελέσματα

 

 

-----Προστέθηκε 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.

 

Ευχαριστώ πολύ για την βοήθεια

Δημοσ.

Λογικά στην περίπτωση που αποστέλλονται 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

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...