程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 一起talk C栗子吧(第一百五十三回:C語言實例

一起talk C栗子吧(第一百五十三回:C語言實例

編輯:關於C

各位看官們,大家好,上一回中咱們說的是計算機中大小端的例子,這一回咱們說的例子是socket通信地址的系統調用 。閒話休提,言歸正轉。讓我們一起talk C栗子吧!

看官們,我們在前面的章回中介紹了套接字的通信地址,這一回中我們將介紹操作套接字通信地址的系統調用。大家都知道套接字的通信地址與套接字的域有關,接下來,我們依據套接字的通信域分別進行介紹。

AF_UNIX域的通信地址

AF_UNIX域的通信地址本質上是文件的目錄,文件目錄存儲在本地計算機中,而且使用該域通信時,通信雙方都位於同一台計算機中。大家可以看到,通信地址和通信雙方都位於同一台計算機中,這樣看來我們不需要擔心通信地址是使用大端方法還是小端方法來存儲,也不用擔心通信過程中傳輸方式是使用大端方法還是小端方法,因為同一台計算機中的存儲方式是固定的。

AF_INET域的通信地址

AF_INET域的通信地址本質上是計算機的IP地址和端口號,它們倆個都存儲於本地計算機中,使用該域通信時,通信雙方屬於不同的計算機,不同的計算機可能會使用不同的存儲方式來存儲它們的IP地址和端口號,究竟使用大端方法還是小端方法,取決於計算機自身的硬件架構,不過有一點是可以確認的,那就是在通信過程中傳輸數據時使用的是大端方法。因此,我們在該域中使用套接字通信時,需要考慮計算機大小端存儲方式對通信的影響。其實,系統設計者已經想到這點了,它為我們提供了通信地址相關的系統調用,通過這些系統調用可以有效地解決大小端的問題。下面我們將詳細介紹這些系統調用。

       uint32_t htonl(uint32_t hostlong);
       uint16_t htons(uint16_t hostshort);
       uint32_t ntohl(uint32_t netlong);
       uint16_t ntohs(uint16_t netshort);

在介紹這些函數前,我們先做一些說明,以方便我們介紹它們:

函數中的h是host的縮寫,表示本地計算機中數據的存儲方式,該方式可能是大端或者小端中的一種。 函數中的n是network的縮寫,表示網絡中數據的存儲方式,其實就是大端方式。 函數中的s是short的縮寫,表示short int類型。 函數中的l是long的縮寫,表示long int類型。 函數中的to表示轉換的意思。

現在我們來看這些函數中的第一個函數:
htonl從名字中就能看出來,它是h到n的轉換,更加准確的說,它是把本地計算機中使用大端或者小端方式存儲的數據轉換為網絡中使用大端方式存儲數據。函數末尾的l表示數據的類型為int long。通常我們叫本地計算機中使用大端或者小端方式存儲的數據為本地字節序數據,而網絡中使用大端方式存儲的數據為網絡字節序數據。因此,函數htonl表示把本地字節序數據轉換為網絡字節序數據,數據的類型為long int。

第一個函數介紹完後,我想大家都能推理出其它函數的功能:

函數 htonl()表示把本地字節序數據轉換為網絡字節數據,數據的類型為int long; 函數 htons()表示把本地字節序數據轉換為網絡字節數據,數據的類型為int short; 函數 ntohl()表示把網絡字節序數據轉換為本地字節數據,數據的類型為int long;

函數 ntohs()表示把網絡字節序數據轉換為本地字節數據,數據的類型為int short;

這些函數都位於同一個頭文件中,使用它們的時候需要包含頭文件:#include 。另外,這些函數是智能的,它的智能性體現在數據轉換的過程中:如果本地字節序和網絡字節序相同,那麼它們就不進行轉換。看來還是有點小聰明呀,哈哈。接下來我們通過代碼來演示一下這些函數的用法:

#include 
#include 

int main()
{
    long int h_data = 0x12345678;
    long int n_data = 0;
    int len = sizeof(long int); // get the count of byte
    int i =-0;
    char *p = (char*)&h_data;

    printf(" host  data \n");
    printf("  [address]   [value] \n");
    while(i<len) {="" printf("[%p]="" [%x]="" \n",p+i,*(p+i));="" i++;="" }="" n_data="htonl(h_data);" convert="" data="" from="" host="" to="" network="" p="(char*)&n_data;" printf("\n="" \n");="" printf("="" [address]="" [value]="" i="" -="len;" while(i

該例子是在上一回例子的基礎上修改的,不同之處在於,我們使用了htonl函數對數據進行了轉換。其它的內容就不詳細介紹了,相信大家都能看明白。另外,我們只使用了htonl函數,其它幾個函數的用法和它的用法完全相同,因此,我們就不一個一個地舉例子說明了。

下面是程序的運行結果,請參考:

host  data 
  [address]   [value] 
[0xbfe19a1c]   [78] 
[0xbfe19a1d]   [56] 
[0xbfe19a1e]   [34] 
[0xbfe19a1f]   [12] 

 network data 
  [address]   [value] 
[0xbfe19a20]   [12] 
[0xbfe19a21]   [34] 
[0xbfe19a22]   [56] 
[0xbfe19a23]   [78] 

從上面的運行結果中可以看到,本地字節序數據和網絡字節序數據的存儲方式正好相反,這也說明了,使用轉換函數是很有必要的。

各位看官,關於socket通信地址系統調用的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved