歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> 網絡編程之-原始套接字

網絡編程之-原始套接字

日期:2017/2/27 9:27:10   编辑:更多Linux

原始套接字可以訪問ICMP和ICMP等協議包,可以讀寫內核不處理的IP數據包。可以創建自定義的IP數據包首部。一句話,使用原始套接字可以

編寫基於IP協議的通訊程序。

1.創建原始套接字具體格式如下:int sockfd;sockfd = socktet(AF_INET, SOCK_RAW, IPPROTO_ICMP);第一個參數:協議族 AF_INET 代表TCP/IP協議第二個參數:SOCKET類型第三個參數:協議類型注意:@如果指定協議為0時,原始套接字可以接收內核傳遞給原始套接字的任何IP數據包,且只有超級用戶才可以創建原始套接字。

@當需要編寫自己的IP數據包首部時,可以在原始套接字上設置套接字選項IP_HDRINCL.在不設置這個選項的情況下,IP協議自動填充IP數據包的首部。

int on = 1;if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)

{ fprintf(stderr, "setsockopt IP_HDRINCL ERROR! \n");exit(1);}

原始套接字直接使用IP協議的套接字,所以是非面向連接的。在這個套接字上可以調用connect和bind函數,分別執行綁定對方和本地地址。

說明:

bind函數:調用bind函數後,發送數據包的源IP地址將是bind函數指定的地址。如是不調用bind,則內核將以發接口的主IP地址填充。如果設置了IP_HDRINCL,那麼必須手工填充每個發送數據包的源IP地址。

connetc函數:調用connect函數後,可以用write和send發送數據包。內核將用這個綁定的地址填充IP數據包的目的IP地址。

發送數據包

使用原始套接字發送數據包必須遵循以下規則:1.如果沒有用connect函數綁定對方地址時,則應使用sendto或sendmsg函數發送數據包,在函數參數中指定對方地址。如果調用了connect函數,則可以直接使用send,write或writev來發送數據包。

2.如果沒有設置IP_HDRINCL選項時,包內可寫的內容為數據部分,內核將自動創建IP首部。如果設置了IP_HDRINCL選項,則包內要填充的內容為IP數據包和首部。內核只負責填充下面兩個域:。如果將IP數據包的標識域設置為0,內核將設置這個域。內核總是計算和填充IP數據包首部的校驗和。

注意:IP數據包首部各個域的內容都是網絡字節順序。

接收數據包

內核遵循以下規則接收數據包:1.UDP和TCP數據包從不傳送給一個原始套接字。如果要查看這兩類數據包,只能通過直接訪問數據鏈路層來實現。

2.大多數ICMP數據包的一個拷貝傳送給匹配的原始套接字。

3.內核處理的所有其它類型的數據包的一個拷貝都傳給匹配的原始套接字。

4.所有內核不能識別的協議類型的IP數據包都傳送給匹配的原始套接字。對於這些IP數據包,內核只做必要的檢驗工作。

在將一個IP數據包傳送給原始套接字之前,內核需要選擇匹配的原始套接字1.數據包的協議域必須與接收原始套接字的協議類型匹配。

2.如果原始套接字調用了bind函數綁定了本地IP地址,那麼到達的IP數據包的源IP地址必須和對方的IP相匹配。

3.如果原始套接字調用connect函數指定了對方的IP地址,則到達的IP數據包的源IP地址秘須與這它相同。




Copyright © Linux教程網 All Rights Reserved