(轉)Linux網絡編程(1):套接字編程簡介

 121人閱讀 評論(0) 收藏 舉報

        這幾天借了一本網絡編程的經典書籍:《UNIX網絡編程(卷一:套接字聯網API)》,想着學習一下網絡編程。下面的內容主要依靠這本書籍,然後,結合我自己的知識和網絡資源,對Linux網絡編程做由淺入深的學習。


1、什麼是套接字(Socket)?

         我自己的理解是:套接字,即端點、端口,是建立在應用層和傳輸層之間的一個概念。

         網絡釋義:套接字,是支持TCP/IP的網絡通信的基本操作單元,可以看做是不同主機之間的進程進行雙向通信的端點,簡單的說就是通信的兩方的一種約定,用套接字中的相關函數來完成通信過程。爲了區別不同的應用進程和連接,許多計算機操作系統爲應用進程與TCP/IP協議交互提供了“套接字接口”,以便區分不同應用進程間的網絡通信和連接。

2、套接字的分類

(1)流式套接字:SOCK_STREAM;用於提供面向連接、可靠的數據傳輸服務,使用了傳輸控制協議,即TCP協議。
(2)數據包套接字:SOCK_DGRAM;用於提供了一種無連接的服務,使用UDP(User Datagram Protocol)協議進行數據的傳輸。

(3)原始套接字:SOCK_RAW;原始套接字可以讀寫內核沒有處理的IP數據包,而流套接字只能讀取TCP協議的數據,數據報套接字只能讀取UDP協議的數據。因此,如果要訪問其他協議發送數據必須使用原始套接字。

3、常用結構體和地址轉換函數

1、通用套接字地址結構:struct sockaddr

  1. struct sockaddr  
  2. {  
  3.     unsigned short sa_family;  
  4.     char      sa_data[14];  
  5. }  

2、Internet下套接字地址結構:struct sockaddr_in

  1. struct sockaddr_in  
  2. {  
  3.     shortsin_family;  //通信協議族,AF_INET、AF_UNIX  
  4.     unsigned short     sin_port;//通信端口  
  5.     struct in_addrsin_addr;//IP地址  
  6.     unsigned charsin_zero[8];  
  7. }  

其中:

  1. struct in_addr    //32位IP地址  
  2. {  
  3.     unsigned long s_addr;  
  4. }  

      struct sockaddr是通用的套接字地址,而struct sockaddr_in則是internet環境下套接字的地址形式,二者長度一樣,都是16個字節。二者是並列結構,指向sockaddr_in結構的指針也可以指向sockaddr。一般情況下,需要把sockaddr_in結構強制轉換成sockaddr結構再傳入系統調用函數中。

3、地址轉換函數

BSD網絡軟件中包含了兩個函數,用來在二進制地址格式(網絡字節序)和點分十進制字符串格式之間相互轉換,但是這兩個函數僅僅支持IPv4。

  1. in_addr_t   inet_addr(const char *cp);//返回32位二進制網絡字節序的IPv4地址  
  2.  int      inet_aton(const char* strptr, struct in_addr *addrptr);  //將strptr所指向的字符串轉換成一個32位的網絡字節序二進制值,並通過指針addrptr來存儲  
  3. char *    inet_ntoa(struct in_addr in);//返回指向一個點分十進制數串的指針,其中n表示32位網絡字節序的IP地址,a表示點分十進制字符串  

功能相似的兩個函數同時支持IPv4和IPv6

  1. const char * inet_ntop(int domain, const void *addr, char *str, socklen_t size);  
  2. int inet_pton(int domain, const char *str, void *addr);//將str所值的字符串轉換成一個32位網絡字節序二進制值,並通過指針addrptr來存儲  

例:

  1. struct sockaddr_in servaddr;  
  2. servaddr.sin_family = AF_INET;  
  3. servaddr.sin_port = htons(8008);  
  4. inet_pton(AF_INET, argv[1], &servaddr.sin_addr);  

4、主機字節序、網絡字節序和字節轉換函數

主機字節序就是我們平常說的大端和小端模式,不同的 CPU 有不同的字節序類型,這些字節序是指整數在內存中保存的順序 。最常見的有兩種:
1. Little endian:將低序字節存儲在起始地址
2. Big endian:將高序字節存儲在起始地址
例子:在內存中雙字0x01020304(DWORD)的存儲方式
內存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04

網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序採用big endian排序方式。


爲了進行兩者之間的轉換,socket提供了轉換的函數 有下面四個字節轉換函數:

htons() :把unsigned short類型從主機序轉換到網絡序

htonl () :把unsigned long類型從主機序轉換到網絡序

ntohs() :把unsigned short類型從網絡序轉換到主機序

ntohl () :把unsigned long類型從網絡序轉換到主機序

另外,我們要知道,16位端口號(一個整形數字),32位IPv4地址(四個整形數字)。

通常的用法是:

  1. #define MYPORT 8008  
  2. int sockfd;  
  3. struct sockaddr_in my_addr;  
  4. sockfd = socket(AF_INET, SOCK_STREAM, 0);   
  5.   
  6. my_addr.sin_family = AF_INET;  /* 主機字節序 */  
  7. my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");  
  8. my_addr.sin_port = htons(MYPORT); /* short, 網絡字節序 */  
  9.   
  10. bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */  
  11. //memset(&my_addr.sin_zero, 0, 8);  
  12.   
  13. bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));  

5、常用端口號

端口:21 

服務:FTP
說明:FTP服務器所開放的端口,用於上傳、下載。最常見的攻擊者用於尋找打開anonymous的FTP服務器的方法。這些服務器帶有可讀寫的目錄。木馬Doly Trojan、Fore、Invisible FTP、WebEx、WinCrash和Blade Runner所開放的端口。

端口:22
服務:Ssh 
說明:PcAnywhere建立的TCP和這一端口的連接可能是爲了尋找ssh。這一服務有許多弱點,如果配置成特定的模式,許多使用RSAREF庫的版本就會有不少的漏洞存在。

端口:23 
服務:Telnet 
說明:遠程登錄,入侵者在搜索遠程登錄UNIX的服務。大多數情況下掃描這一端口是爲了找到機器運行的操作系統。還有使用其他技術,入侵者也會找到密碼。木馬Tiny Telnet Server就開放這個端口。

端口:25
服務:SMTP 
說明:SMTP服務器所開放的端口,用於發送郵件。入侵者尋找SMTP服務器是爲了傳遞他們的SPAM。入侵者的帳戶被關閉,他們需要連接到高帶寬的E-MAIL服務器上,將簡單的信息傳遞到不同的地址。木馬Antigen、Email Password Sender、Haebu Coceda、Shtrilitz Stealth、WinPC、WinSpy都開放這個端口。

端口:53
服務:Domain Name Server(DNS) 
說明:DNS服務器所開放的端口,入侵者可能是試圖進行區域傳遞(TCP),欺騙DNS(UDP)或隱藏其他的通信。因此防火牆常常過濾或記錄此端口。

端口:80
服務:HTTP 
說明:用於網頁瀏覽。木馬Executor開放此端口。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章