2013-10-06 4 views
25

Ich bin neu in der Socket-Programmierung und ich versuche, die Funktionsweise von htons() zu verstehen. Ich habe ein paar Tutorials im Internet wie this und this ein Beispiel gelesen. Aber ich konnte nicht verstehen, was htons() genau macht. Ich habe versucht, den folgenden Code:htons() Funktion in Socket Programmierung

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

int main(int argc, char *argv[]) 
{ 
    int sockfd, newsockfd, portno, clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 

    /* First call to socket() function */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) 
    { 
     perror("ERROR opening socket"); 
     exit(1); 
    } 
    /* Initialize socket structure */ 
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno = 5001; 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 

    /* Now bind the host address using bind() call.*/ 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, 
          sizeof(serv_addr)) < 0) 
    { 
     perror("ERROR on binding"); 
     exit(1); 
    } 

    /* Now start listening for the clients, here process will 
    * go in sleep mode and will wait for the incoming connection 
    */ 
    listen(sockfd,5); 
    clilen = sizeof(cli_addr); 

    /* Accept actual connection from the client */ 
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, 
           &clilen); 
    if (newsockfd < 0) 
    { 
     perror("ERROR on accept"); 
     exit(1); 
    } 
    /* If connection is established then start communicating */ 
    bzero(buffer,256); 
    n = read(newsockfd,buffer,255); 
    if (n < 0) 
    { 
     perror("ERROR reading from socket"); 
     exit(1); 
    } 
    printf("Here is the message: %s\n",buffer); 

    /* Write a response to the client */ 
    n = write(newsockfd,"I got your message",18); 
    if (n < 0) 
    { 
     perror("ERROR writing to socket"); 
     exit(1); 
    } 
    return 0; 
} 

Der Wert sin_port wurde als 35091 gezeigt, während das Debuggen und ich verstehe nicht, wie portno5001-35091 geändert. Kann jemand bitte den Grund für diese Wertänderung erklären?

+1

Was verstehen Sie, was 'htons()' tut? Hast du das gelesen: http://en.wikipedia.org/wiki/Endianess. –

+0

Gemäß Linux-Handbuch Die Funktion 'htons()' konvertiert den unsigned short integer hoseshort von der Host-Byte-Reihenfolge in die Netzwerk-Byte-Reihenfolge. – Shushant

+0

Ich kenne große Endianne und kleine Endianne, aber ich weiß nicht die Operation von htons() genau !!! – User123422

Antwort

20

htons ist host-to-network short

Das bedeutet, es auf 16-Bit-Kurz ganzen Zahlen arbeitet. d.h. 2 Bytes.

Diese Funktion tauscht die Endianz eines Kurzschlusses aus.

Ihre Nummer beginnt bei:

0001 0011 1000 1001 = 5001

Wenn die endianness geändert wird, es tauscht die beiden Bytes:

1000 1001 0001 0011 = 35091

+0

meinst du, dass 0001 0011 Host-Bytes und 1000 1001 sind Netzwerk-Byes? – User123422

+1

@ User123422 nein, du hast es falsch verstanden. Auch wenn die binäre Form von 5001 "0001 0011" ist, speichert sie beim Speichern in einer LittleEndian-Maschine Bytes in der umgekehrten Reihenfolge ("1000 1001" 0001 0011 "). Denk darüber nach; Wenn 'A' und 'B' jeweils acht Bits darstellen, wird die Binärzahl 'AB' in einer LittleEndian-Maschine als 'BA' gespeichert (google 'Endianness', wenn Sie wissen wollen, warum). "htons()" ist eine praktische Funktion, die verwendet wird, um eine beliebige Abkürzung in das BigEndian-Format ("AB" -Format) zu konvertieren, da dies die "Netzwerk-Byte-Reihenfolge" ist. – Anubis

3

die htons() Funktion wandelt Werte zwischen Host- und Netzwerk-Byte- Aufträge. Es gibt einen Unterschied zwischen big-endian und little-endian und Netzwerk-Byte-Reihenfolge abhängig von Ihrem Computer und Netzwerkprotokoll in Verwendung.

67

Es hat mit der Reihenfolge zu tun, in der Bytes im Speicher gespeichert sind. Die Dezimalzahl 5001 ist 0x1389 in Hexadezimal, so dass die beteiligten Bytes 0x13 und 0x89 sind. Viele Geräte speichern Zahlen in little-endian Format, was bedeutet, dass das niedrigstwertige Byte zuerst kommt. So in diesem speziellen Beispiel bedeutet dies, dass die Zahl 5001 im Speicher wird als

gespeichert werden macht
0x89 0x13 

Die htons() Funktion sicher, dass Zahlen im Speicher in Netzwerk-Byte-Reihenfolge gespeichert sind, die zuerst mit dem höchstwertigen Byte ist. Es wird daher die Bytes tauscht die Zahl bilden, so dass im Speicher wird die Bytes

0x13 0x89 

Auf einer Little-Endian Maschine, die Nummer mit dem vertauschten Bytes in der Reihenfolge gespeichert wird, ist 0x8913 in hexadezimal, die ist 35091 in Dezimalschreibweise. Beachten Sie, dass die Funktion htons() keinen Austausch durchführen muss, wenn Sie an einem big-endian-Rechner arbeiten, da die Nummer bereits richtig im Speicher gespeichert wird.

Der zugrunde liegende Grund für all diese Swapping hat mit den verwendeten Netzwerkprotokollen zu tun, die erfordern, dass die übertragenen Pakete die Netzwerk-Byte-Reihenfolge verwenden.