2013-10-06 41 views
25

我是套接字編程的新手,我試圖理解htons()的操作。我已經閱讀了互聯網上的一些教程,例如thisthis。但我無法理解htons()究竟做了什麼。我嘗試下面的代碼:套接字編程中的htons()函數

#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; 
} 

sin_port的值顯示爲35091在調試時,我不知道如何改變portno500135091。有人可以解釋價值變化的原因嗎?

+1

你對什麼是htons()有什麼瞭解?你讀過這個:http://en.wikipedia.org/wiki/Endianness。 –

+0

根據Linux手冊'htons()'函數將無符號短整數主機從主機字節順序轉換爲網絡字節順序。 – Shushant

+0

我知道大Endianne和小Endianne,但我不知道htons()正確的操作! – User123422

回答

20

htonshost-to-network short

這意味着它可以在16位的短整數。即2個字節。

此函數交換短的字節序。

0001 0011 1000 1001 = 5001

當字節順序發生了變化,交換兩個字節:

1000 1001 0001 0011 = 35091

+0

你的意思是0001 0011是主機字節,1000 1001是網絡版本? – User123422

+1

@ User123422不行,你錯了。即使 - 雖然5001的二進制形式是「'0001 0011''1000 1001'」,但將它存儲在LittleEndian機器中時,它將以相反的順序(「'1000 1001''0001 0011'」)存儲字節。想想這個;如果'A'和'B'分別代表8位,則二進制數字'AB'將被存儲爲LittleEndian機器中的'BA'(如果您需要知道原因,則可將其存儲爲「Google Endianness」)。 'htons()'是一個方便的函數,用於將任何給定的短語轉換爲BigEndian格式('AB'格式),因爲這是'網絡字節順序'。 – Anubis

3

htons()功能的主機和網絡字節之間轉換值

您的號碼在開出命令。 big-endianlittle-endian和網絡字節順序有所不同,具體取決於您所使用的機器和網絡協議。

67

它與字節存儲在內存中的順序有關。十進制數5001爲十六進制的0x1389,所涉及的字節數爲0x130x89。許多設備存儲數字little-endian格式,這意味着最低有效字節首先。因此,在這個特定的例子這意味着在內存中的數字5001將被存儲爲

0x89 0x13 

htons()函數確保數字存儲在網絡字節順序,這是最顯著字節第一存儲器。因此,將交換構成數個字節,使得在存儲器中的字節將被存儲在順序

0x13 0x89 

在一個小端機,對換字節數是0x8913十六進制的,其中以十進制表示法爲35091。請注意,如果您正在使用big-endian機器,則htons()函數不需要進行任何交換,因爲編號已經以正確的方式存儲在內存中。

所有這些交換的根本原因與使用中的網絡協議有關,它們要求傳輸的數據包使用網絡字節順序。