學習--原始套接字(轉)
學習--原始套接字(轉)[@more@]原始套接字可以訪問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! ");
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地址秘須與這它相同。
編寫基於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! ");
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地址秘須與這它相同。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-958639/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 套接字為什麼叫套接字?
- 網路套接字
- IPC之套接字
- 《UNIX網路程式設計》筆記 - 套接字選項/UDP套接字程式設計筆記UDP
- python UDP套接字通訊PythonUDP
- Python 套接字內建方法Python
- 01啟動(關閉)套接字
- 基本TCP套接字程式設計APITCP程式設計API
- 20.7 OpenSSL 套接字SSL加密傳輸加密
- 編寫socket套接字的步驟
- nginx建立和監聽套接字分析Nginx
- Unix 套接字程序通訊初探【Go 版本】Go
- 14.1 Socket 套接字程式設計入門程式設計
- Unix 套接字程序通訊初探【Java 版本】Java
- WebKit 原始碼學習: 代理轉發器 WKScrollViewDelegateForwarderWebKit原始碼ViewForward
- 計算機網路之十一:套接字Socket計算機網路
- 學習心得之華為數字化轉型框架框架
- 安全套接字層證書是什麼
- Oracle叢集技術 | OLR與套接字檔案(二)Oracle
- Linux 下的程式間通訊:套接字和訊號Linux
- 原始碼學習原始碼
- Linux中什麼是套接字檔案?有什麼作用?Linux
- C++關於DLL中建立套接字的問題(求教)C++
- Oracle 叢集的自啟動,OLR與套接字檔案Oracle
- fishhook原始碼學習Hook原始碼
- MMKV原始碼學習原始碼
- vue原始碼學習Vue原始碼
- 【原始碼學習】ThreadLocal原始碼thread
- EventBus原始碼學習原始碼
- ObjectMapper原始碼學習ObjectAPP原始碼
- express原始碼學習Express原始碼
- go原始碼學習Go原始碼
- 學習HashMap原始碼HashMap原始碼
- Web【轉載學習】Web
- [轉]memcached學習系列
- python學習之數字Python
- 【Socket程式設計】【第一節】【Socket基本原理和套接字】程式設計
- 傳輸層協議、應用層、socket套接字、半連結池協議
- 【網路程式設計】TCPIP-8-套接字的多種選項程式設計TCP