2012-04-08 17 views
2

Ich möchte eine Struktur von meinem Client-Programm an ein Server-Programm senden (ich schreibe sowohl die Server-und die Client-Programme). Wenn es wichtig ist, schreibe ich auch auf einem 32-Bit-Betriebssystem Linux, und sowohl der Client als auch der Server werden auf denselben Systemen ausgeführt. Hier ist meine Struktur:Client-Server-Kommunikation über Sockets

struct msg_to_server { 
    int type_of_msg; 
    int type; 
    int flag; 
    int pid; 
    char name[MAX_WORD]; 
    char client_name[MAX_WORD]; 
    int child_timeout; 
    int numberKilled; 
}; 

Ich weiß, dass, wenn ich ein int sende ich brauche htonl zu verwenden (int) die unsigned int vom Host-Byte-Reihenfolge zu konvertieren Byte-Reihenfolge zu vernetzen, aber was soll ich tun, falls einer Struktur? Jede Hilfe würde sehr geschätzt werden.

Antwort

4

Wenn Sie wissen, dass Sie von der gleichen Art von Systemen senden und empfangen, müssen Sie keine Ganzzahlen in die Byte-Reihenfolge des Netzwerks konvertieren. Das ist nur wichtig, wenn Sie zwischen Systemen mit unterschiedlicher Endianz senden.

Sie können die Bytes der gesamten Struktur einfach über den Socket senden, ohne dass ein Übersetzungsschritt erforderlich ist.

// client 
struct msg_to_server msg; 
send(sock, &msg, sizeof(msg), 0); 

// server 
struct msg_to_server msg; 
ssize_t n = recv(sock, &msg, sizeof(msg), 0); 

Beachten Sie jedoch, dass, wenn Sie TCP verwenden, dann das Protokoll nicht alle Bytes zurückgeben können Sie auf recv() anfordern. Möglicherweise müssen Sie mehrmals die recv() aufrufen, um alle vom Client gesendeten Bytes abzurufen. Wenn Sie UDP verwenden, müssen Sie sich keine Gedanken darüber machen, aber Sie werden andere Überlegungen wie unzuverlässige Lieferung haben.

+0

Diese Lösung kann zerbrechlich sein, auch wenn Sender und Empfänger die gleiche Hardware und dasselbe Betriebssystem sind: z.B.Wenn das sendende Programm mit anderen Compilereinstellungen kompiliert wurde als das empfangende Programm, dann könnte dieselbe Struktur auf den beiden Systemen ein anderes Speicherlayout haben, so dass die Bytes auf dem Empfänger unterschiedlich interpretiert werden. –

+0

Ja, deshalb habe ich "mindestens" gesagt. Beim Senden von Daten zwischen zwei Computern müssen viele mögliche Probleme berücksichtigt werden. Es ist jedoch ziemlich einfach in einer kontrollierten Umgebung zu lösen. –

+0

Danke euch beiden. Das sind hilfreiche Kommentare. Das wusste ich nicht. –

3

F: Ich weiß, dass, wenn ich ein int sende ich htonl (int) zu verwenden müssen, die unsigned int vom Host-Byte-Reihenfolge umwandeln Byte-Reihenfolge zu vernetzen, aber was soll ich tun im Falle einer Struktur?

1) Als Greg Hewgill richtig angegeben:

Wenn Sie wissen, Sie senden und von der gleichen Art von Systemen empfängt, dann gibt es keine Notwendigkeit zu konvertieren Byte-Reihenfolge zu vernetzen.

2) Andernfalls, wenn Sie denken, Sie könnten jemals diese binäre Struktur mit einem nicht-Little-Endian-Host austauschen möchten, dann müssen Sie verwenden htonl/ntohl und htons/ntohs auf einem Feld-für-Feld-Basis; wenn Sie senden und wenn Sie erhalten.

3) Die beste Weise tragbar, aber zu sein, ist zu vermeiden binäre Aufzeichnungen über das Netzwerk gesendet werden.

Genau hier leuchten Formate wie XML oder JSON.

Und warum Internet-Standards (wie HTTP und SMTP, unter anderem) neigen dazu, Text basierend sein.

Ich würde auf jeden Fall textuelle Datensätze (z. B. XML) zwischen Hosts austauschen, wenn überhaupt möglich.

IMHO ...

Verwandte Themen