socket編程——sockaddr_in結構體操做

sockaddr結構體

sockaddr的缺陷: struct sockaddr 是一個通用地址結構,這是爲了統一地址結構的表示方法,統一接口函數,使不一樣的地址結構能夠被bind() , connect() 等函數調用;sa_data把目標地址和端口信息混在一塊兒了網絡

struct sockaddr {  
     unsigned short sa_family;
   char sa_data[14];                  
   }; 
sa_family是通訊類型,最經常使用的值是 "AF_INET"
sa_data14字節,包含套接字中的目標地址和端口信息


  
   sockaddr_in 結構體:struct sockaddr_in中的in 表示internet,就是網絡地址,這只是咱們比較經常使用的地址結構,屬於AF_INET地址族,他很是的經常使用
sockaddr_in結構體解決了sockaddr的缺陷,把port和addr 分開儲存在兩個變量中socket

struct sockaddr_in { 
   short int sin_family;
   unsigned short int sin_port; 
     struct in_addr sin_addr;
struct in_addr { 
    unsigned long s_addr;
           }
                
     unsigned char sin_zero[8];
}   


   sin_port和sin_addr都必須是NBO
通常可視化的數字都是HBO(本機字節順序)

    sin_zero 初始值應該使用函數 bzero() 來所有置零。
   通常採用下面語句函數

struct sockaddr_in cliaddr;
bzero(&cliaddr,sizeof(cliaddr));

  

   sockaddr_in結構體變量的基本配置spa

struct sockaddr_in ina;

bzero(&ina,sizeof(ina));

ina.sin_family=AF_INET;

ina.sin_port=htons(23);
ina.sin_addr.s_addr = inet_addr("132.241.5.10");  



    sockaddr 和 sockaddr_in的相互關係
通常先把sockaddr_in變量賦值後,強制類型轉換後傳入用sockaddr作參數的函數指針

  •     sockaddr_in用於socket定義和賦值
  •     sockaddr用於函數參數


   最典型的源、目的節點socket定義
對於源、目的地址和源、目的地址端口,須要創建兩個socket變量
cliaddr綁定源地址和源端口
servaddr用於connect和sendto的設定目的地址和目的端口server

struct sockaddr_in servaddr,cliaddr;

create_socket(char *server_addr_string,unsigned int server_port)
{
源socket賦值
       bzero(&cliaddr,sizeof(cliaddr));
       cliaddr.sin_family = AF_INET;
       一般TCP/UDP 協議源地址和端口都是隨機的
       cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
       cliaddr.sin_port = htons(0);

目的socket賦值
       bzero(&servaddr,sizeof(servaddr));
       servaddr.sin_family = AF_INET;
       inet_aton(server_addr_string,&servaddr.sin_addr);
       servaddr.sin_port = htons(server_port);
}



    網絡字節順序 (Network Byte Order)      NBO
結構體的sin_port和sin_addr都必須是NBO

   本機字節順序 (Host Byte Order)    HBO
通常可視化的數字都是HBO

    NBO,HBO兩者轉換
inet_addr()    將字符串點數格式地址轉化成無符號長整型(unsigned long s_addr s_addr;)
inet_aton()    將字符串點數格式地址轉化成NBO
inet_ntoa ()     將NBO地址轉化成字符串點數格式
htons()    "Host to Network Short"
htonl()    "Host to Network Long"
ntohs()    "Network to Host Short"
ntohl()    "Network to Host Long"
經常使用的是htons(),inet_addr()正好對應結構體的端口類型和地址類型

    三種給socket賦值地址的方法接口

inet_aton(server_addr_string,&myaddr.sin_addr);
myaddr.sin_addr.s_addr = inet_addr("132.241.5.10");
INADDR_ANY轉不轉NBO隨便
myaddr.sin_addr.s_addr = htons(INADDR_ANY);  
myaddr.sin_addr.s_addr = INADDR_ANY;



    兩種給socket 賦值端口的方法ci

#define MYPORT 3490 
myaddr.sin_port = htons(MYPORT);
0(隨機端口)轉不轉NBO隨便
myaddr.sin_port = htons(0);
myaddr.sin_port = 0;  



    htons/l和ntohs/l等數字轉換都不能用於地址轉換,由於地址都是點數格式,因此地址只能採用數字/字符串轉換如inet_aton,inet_ntoa;
惟一能夠用於地址轉換的htons是針對INADDR_ANY
 cliaddr.sin_addr.s_addr = htons(INADDR_ANY)

   inet_addr()與inet_aton()的區別字符串

  •     inet_addr()    是返回值型
struct sockaddr_in ina;

ina.sin_addr.s_addr = inet_addr("132.241.5.10"); 
  •     inet_aton()     是參數指針型
struct sockaddr_in ina;

inet_aton("132.241.5.10",&ina.sin_addr);



   inet_ntoa  將NBO地址轉化成字符串點數格式
參數:結構體變量.sinaddr
返回值:字符串指針string

a1 = inet_ntoa(ina.sin_addr);
printf("address 1: %s\n",a1); 
address 1: 132.241.5.10 

    inet_addr()的缺陷:必須對-1作檢測處理 由於inet_addr()的結果是整型,而發生錯誤時返回-1。 而 ina.sin_addr.s_addr是unsigned long型 -1在long short顯示成111111111,和IP地址255.255.255.255相符合!會被誤認爲廣播地址!

相關文章
相關標籤/搜索