[gcc編程] socket編程—— sockaddr_in結構體操作

來源:互聯網
上載者:User

 轉: http://blog.sina.com.cn/s/blog_6151984a0100etj1.html

 

 

sockaddr結構體
sockaddr的缺陷:sa_data把目標地址和連接埠資訊混在一起了
struct sockaddr {  
    
unsigned short sa_family;
   char
sa_data[14];                  

   }; 

sa_family是通訊類型,最常用的值是 "AF_INET"
sa_data14位元組,包含通訊端中的目標地址和連接埠資訊

  
  sockaddr_in 結構體
sockaddr_in結構體解決了sockaddr的缺陷,把port和addr 分開儲存在兩個變數中

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結構體變數的基本配置

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的設定目的地址和目的連接埠

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
賦值連接埠的方法

#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
傳回值:字串指標

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相
符合!會被誤認為廣播位址!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.