套接字


1.創建socket

  sk = socket(int family, int type, int protocol);

  family:協議簇,PF_INET、PF_INET6、PF_PACKET等等。

  type:類型,SOCK_DGRAM、SOCK_STREAM、SOCK_RAW等等。

  protocol:協議,協議簇上面的協議,這個字段不可以使用組合方式,只能使用一個(例如不能使用IPPROTO_UDP|IPPROTO_ICMP)。

  協議棧收到數據包是從family開始匹配的,之后匹配type,protocol,如果family是PF_PACKET,則繼續匹配protocol(此時沒有類型區分)。

2.socket參數組合

  [1]創建INET TCP/UDP socket:

    socket(PF_INET,  SOCK_DGRAM,  IPPROTO_UDP);   //創建UDP socket,第三個參數可以填0,填0默認是用UDP類型

    socket(PF_INET,  SOCK_STREAM,  IPPROTO_TCP);   //創建TCPsocket,第三個參數可以填0,填0默認是用TCP類型

    收到的為應用層數據,發送時填充應用層數據。

  [2]創建INET RAW socket:

    socket(PF_INET,  SOCK_RAW,  IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP);

    收到的是從IP頭開始的數據,發送時從IP協議之后填充,例如UDP協議時填充UDP頭+應用數據,TCP則填充TCP頭+應用數據。

    如果設置了IP_HDRINCL選項:setsockopt(sk, IPPROTO_IP, IP_HDRINCL, &option, sizeof(option)),則UDP協議時發送時填充IP頭+UDP頭+應用數據。

    socket(PF_INET,  SOCK_RAW,  IPPROTO_RAW);  //收發都是從ip頭開始,等於自動設置IP_HDRINCL選項

  [3]創建鏈路層socket:

    socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))

    收到的是從二層頭開始的完整數據包,當第三個參數是ETH_P_ALL時,可以接收到從本機發出去的數據包。

 

    socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))

    收到的是從二層頭上面開始的數據包。

3.總結

  [1]SOCK_RAW類型通常稱為"原始套接字",這里的"原始"是相對來說的,例如協議簇是PF_INET時,則原始就是IP層的起始。協議簇是PF_PACKET時,則原始就是二層的起始。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM