Linux網絡編程之套(tao)接字
							時間:2014-10-21      來源(yuan):未知 
							一(yi) :套接字屬性
套接字由域(domain),類型(type)和(he)協議(protocol)三個屬性確定其特性。
1)套接字的(de)域
域指定套(tao)接字通信中(zhong)使用的(de)網(wang)絡(luo) 介質,常見的(de)套(tao)接字域是AF_INET,它(ta)指的(de)是互聯網(wang)絡(luo),許多(duo)LINUX局域網(wang)使用的(de)都是該網(wang)絡(luo)。
服(fu)(fu)務器(qi)上(shang)可能(neng)同時有多個(ge)(ge)(ge)服(fu)(fu)務正(zheng)在運行,客戶可以通過IP端(duan)(duan)口(kou)來(lai)指定(ding)一(yi)臺聯網(wang)機(ji)器(qi)上(shang)的(de)某個(ge)(ge)(ge)特(te)定(ding)服(fu)(fu)務。在系統(tong)內部,端(duan)(duan)口(kou)通過分配一(yi)個(ge)(ge)(ge)唯一(yi)的(de)16位整數來(lai)標(biao)識(shi),在系統(tong)外部,則(ze)需要(yao)通過IP地址和端(duan)(duan)口(kou)號的(de)組合(he)來(lai)確定(ding)。套接字作為通信(xin)的(de)終點,它必須(xu)在開(kai)始(shi)通信(xin)之前綁定(ding)一(yi)個(ge)(ge)(ge)端(duan)(duan)口(kou)。
服務器在特(te)定的(de)(de)(de)(de)端口等待客(ke)戶(hu)的(de)(de)(de)(de)連接,知名服務器所分配的(de)(de)(de)(de)端口號(hao)在所有LINUX和UNIX機器上都是(shi)一(yi)樣的(de)(de)(de)(de),它們通常(chang)(但(dan)并(bing)不總(zong)是(shi)如此)小于1024,一(yi)般情(qing)況下,小于1024的(de)(de)(de)(de)端口號(hao)都是(shi)為系統(tong)服務保留的(de)(de)(de)(de),并(bing)且所服務的(de)(de)(de)(de)進程必須具(ju)有超級用戶(hu)權限。
其它可以使用的(de)域如(ru)AF_UNIX,AF_ISO,AF_XFA等。
2)套(tao)接字類型(xing)
套(tao)接(jie)(jie)字(zi)有三(san)種(zhong)類型:流式套(tao)接(jie)(jie)字(zi)(SOCK_STREAM),數據(ju)報(bao)套(tao)接(jie)(jie)字(zi)(SOCK_DGRAM)及原始套(tao)接(jie)(jie)字(zi)。
1、流式(shi)套接字(SOCK_STREAM)
流式套(tao)接(jie)字(zi)提供的是(shi)一個有序,可靠,雙向字(zi)節流的連接(jie)。因此,發(fa)(fa)送的數據可以(yi)確保不(bu)會丟失,復制或亂序到達,并且在這一過(guo)程 中發(fa)(fa)生的錯誤(wu)也不(bu)會顯(xian)示出來(lai)。流式套(tao)接(jie)字(zi)由類型(xing)SOCK_STREAM指定(ding),它們是(shi)地AF_INET域中通過(guo)TCP/IP連接(jie)來(lai)實現的,它們也是(shi)AF_UNIX域中常用的套(tao)接(jie)字(zi)類型(xing)。
2、數(shu)據報套接字(SOCK_DGRAM)
與此相(xiang)反 ,由SOCK_DGRAM指(zhi)定的(de)(de)數據(ju)報(bao)套接(jie)字不(bu)建立(li)(li)和維(wei)持(chi)一(yi)個連(lian)接(jie),它(ta)(ta)尋可以(yi)發送的(de)(de)數據(ju)報(bao)的(de)(de)長度(du)有限制(zhi)(zhi)。數據(ju)報(bao)作為(wei)一(yi)個單獨的(de)(de)網(wang)絡消息被傳(chuan)輸,它(ta)(ta)可能(neng)會丟失,復制(zhi)(zhi)或亂序(xu)到達。數據(ju)報(bao)套接(jie)字是在AF_INET域中通(tong)過(guo)UDP/IP連(lian)接(jie)來(lai)(lai)實現的(de)(de),它(ta)(ta)提供(gong)的(de)(de)是一(yi)種(zhong)無(wu)序(xu)的(de)(de)不(bu)可靠服務,但從資源(yuan)的(de)(de)角(jiao)度(du)來(lai)(lai)看,相(xiang)對來(lai)(lai)說它(ta)(ta)們開銷(xiao)比較小,因為(wei)不(bu)需(xu)要維(wei)持(chi)網(wang)絡連(lian)接(jie),而(er)且因為(wei)無(wu)需(xu)花費時(shi)間來(lai)(lai)建立(li)(li)連(lian)接(jie),它(ta)(ta)們的(de)(de)速度(du)也很快(kuai)。
3、原始套接(jie)字
二 :套接字協議
只要(yao)底層傳輸機制允許(xu)不(bu)止一(yi)(yi)個協(xie)議來(lai)提供所要(yao)求(qiu)的(de)套接(jie)字(zi)類型,就可(ke)以為套接(jie)字(zi)選擇(ze)(ze)一(yi)(yi)個特(te)定的(de)協(xie)議。我(wo)們重點討論UNIX網絡(luo)套接(jie)字(zi)和文件系統套接(jie)字(zi),它們不(bu)需(xu)要(yao)你 選擇(ze)(ze)一(yi)(yi)個特(te)定的(de)協(xie)議,只需(xu)要(yao)使用其默認值即可(ke)。
三(san) :創建套接(jie)字
 socket系統調用創建一個套接字并返回一個描述符,該描述符可以用來訪問該套接字。
         #include < sys/types.h>
         #include < sys/socket.h>
          socket函數原型為:
          int socket(int domain, int type, int protocol);
domain參數指定socket的類型,一般為AF_INET,type可(ke)以是SOCK_STREAM 或SOCK_DGRAM,分別(bie)表示TCP連(lian)接(jie)和UDP連(lian)接(jie);protocol通常賦值"0"。Socket()調用返(fan)回一個整型socket描述符,你(ni)可(ke) 以在后面(mian)的調用使用它。
一(yi)(yi)旦通過socket調用返回(hui)一(yi)(yi)個socket描述符,你(ni)應該(gai)將(jiang)該(gai)socket與你(ni)本(ben)機上的一(yi)(yi)個端(duan)(duan)口(kou)相關聯(往(wang)往(wang)當你(ni)在(zai)設計服(fu)務(wu)器端(duan)(duan)程序時(shi)需要調用該(gai)函數(shu)。隨后你(ni)就可以在(zai)該(gai)端(duan)(duan)口(kou)監聽服(fu)務(wu)請求;而客戶(hu)端(duan)(duan)一(yi)(yi)般無須調用該(gai)函數(shu))。
五:套(tao)接字地址
每(mei)個套(tao)接字域(yu)都有(you)其(qi)自己的地址格式。對(dui)于AF_INET域(yu)來(lai)說(shuo),套(tao)接字地址由結構sockaddr_in來(lai)指定,該結構在頭文件netinet/in.h中定義。
 我們要討論的第一個結構類型是:struct sockaddr,該類型是用來保存socket信息的:
         struct sockaddr
         { 
           unsigned short sa_family; /* 地址族, AF_xxx */ 
               char sa_data[14]; /* 14 字節的協議地址 */
          };
sa_family一(yi)般為AF_INET;sa_data則(ze)包含該(gai)socket的(de)IP地址和(he)端口號(hao)。
  另外還有一種結構類型:
         struct sockaddr_in
          { 
           short int sin_ family; /* 地址族 */ 
            unsigned short int sin_port; /* 端口號 */ 
            struct in_addr sin_addr; /* IP地址 */ 
             unsigned char sin_zero[8]; /* 填充0 以保持與struct sockaddr同樣大小 */ 
    };
這(zhe)個結構使用更(geng)為方便。sin_zero(它用來將(jiang)sockaddr_in結構填充到與(yu)struct sockaddr同樣(yang)的(de)(de)(de)長度)應(ying)該用bzero()或memset()函(han)數將(jiang)其置為零。指向sockaddr_in 的(de)(de)(de)指針和指向sockaddr的(de)(de)(de)指針可以相互轉(zhuan)換,這(zhe)意味著如(ru)果(guo)一個函(han)數所需參數類型是sockaddr時,你可以在函(han)數調用的(de)(de)(de)時候將(jiang)一個指向 sockaddr_in的(de)(de)(de)指針轉(zhuan)換為指向sockaddr的(de)(de)(de)指針;或者相反。sin_family通常被賦AF_INET;sin_port和 sin_addr應(ying)該轉(zhuan)換成(cheng)為網絡(luo)字節優(you)先順(shun)序 。
  IP地址結構struct in_addr被定義為:
         struct in_addr
          {
                 unsigned long int s_addr;
          };
IP地址(zhi)中的四(si)個(ge)字節組成(cheng)一個(ge)32位(wei)的值。
 這是幾個字節順序轉換函數:
         htons()--"Host to Network Short" ; htonl()--"Host to Network Long" 
    ntohs()--"Network to Host Short" ; ntohl()--"Network to Host Long"
在這里,h表(biao)示"host" ,n表(biao)示"network",s 表(biao)示"short",l表(biao)示 "long"。

