套接字

1.建立socket數組

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

  family:協議簇,PF_INET、PF_INET六、PF_PACKET等等。ip

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

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

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

2.socket參數組合協議

  [1]建立INET TCP/UDP socket:co

    socket(PF_INET,  SOCK_DGRAM,  IPPROTO_UDP);   //建立UDP socket,第三個參數能夠填0,填0默認是用UDP類型protocol

    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時,則原始就是二層的起始。

相關文章
相關標籤/搜索