套接字設置

套接字設置

      利用套接字能完成很多豐富得應用,但要想利用套接字實現更復雜得應用,必定會涉及到調整套接字屬性,通過調整套接字屬性,能夠實現廣播、組播、地址重用、數據緩衝區以及數據超時處理等功能。

 int getsockopt(int sockfd, int level, int optname,  void *optval, socklen_t *optlen);

 int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

參數sockfd----用於指定要操作的套接字

level ----- 用於指定套接字的操作層次,及當前要操作得協議層次

SOL_SOCKET :通用套接字層,用於設置通用套接字

IPPROTO_IP    IP協議層,用於設置IP

IPPROTO_TCPTCP協議層,用於設置TCP

       參數optname\optval\optlen3個相關得參數,optname對應選項名稱,及針對那個選項設置,optval是選項所採用得數據結構,optlen是數據結構所佔的字節數。以上3個參數的配置取決於level參數得設置。

選項名稱        說明                  數據類型
========================================================================
SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST      允許發送廣播數據            int
SO_DEBUG        允許調試                int
SO_DONTROUTE      不查找路由int
SO_ERROR        獲得套接字錯誤             int
SO_KEEPALIVE      保持連接                int
SO_LINGER        延遲關閉連接              struct linger
SO_OOBINLINE      帶外數據放入正常數據流         int
SO_RCVBUF接收緩衝區大小int
SO_SNDBUF發送緩衝區大小int
SO_RCVLOWAT       接收緩衝區下限             int
SO_SNDLOWAT       發送緩衝區下限             int
SO_RCVTIMEO接收超時struct timeval
SO_SNDTIMEO發送超時  struct timeval
SO_REUSEADDR允許重用本地地址和端口int
SO_TYPE         獲得套接字類型             int
SO_BSDCOMPAT      與BSD系統兼容              int
========================================================================
IPPROTO_IP
------------------------------------------------------------------------
IP_HDRINCL       在數據包中包含IP首部          int
IP_OPTINOSIP首部選項               int
IP_TOS服務類型
IP_TTL         生存時間                int

IP_ADD_MEMBERSHIP  組播                sizeof(ip_mreq)
========================================================================
IPPRO_TCP
------------------------------------------------------------------------
TCP_MAXSEGTCP最大數據段的大小           int
TCP_NODELAY       不使用Nagle算法             int
========================================================================

套接字設置應用:

    1、數據收發時限設置

    這項功能是設置數據包得接收與發送時限,以提升應用程序性能,即在規定的時間內,如果沒有數據到來或數據包沒有發送成功,則轉入相應模塊進行處理。

     Struct timeval timeout;

timeout . tv_sec = 5;

timeout . tv_usec = 0;

//接收時限

setsockopt( serversocket , SOL_SOCKET, SO_RECVTIMEO,(char *)&timeout, sizeof(timeoout));

//發送時限

setsockopt( serversocket , SOL_SOCKET, SO_SNDTIMEO,(char *)&timeout, sizeof(timeoout));

  2、修改數據收發緩存區  

      在接收與發送數據時,由於實際數據可能遠遠大於默認緩存區得大小,要想解決這個問題,除了可以循環調用接收與發送函數以外,還可以通過設置SO_RCVBUFSO_SNDBUF屬性得方式完成。

//接收緩衝區

int opt = 1024 * 1024;

setsockopt( serversocket, SOL_SOCKET, SO_RCVBUF,(const char *) &opt, sizeof(opt));

//發送緩衝區

setsockopt( serversocket, SOL_SOCKET, SO_SNDBUF,(const char *) &opt, sizeof(opt));

 

3、廣播設置

在發送數據包的時候,若希望該Socket發送得數據具有廣播特性,則要進行下列得設置:

       int bBroadcast = 1;

setsockopt(serversocket, SOL_SOCKET, SO_BROADCAST, (const char *) &bBroadcast, sizeof(bBroadcast));

      4、直接數據複製

爲提升系統性能,在發送或接收數據時,可以主動設置數據不經歷由系統緩存區到套接字緩存區的拷貝,這個功能是由設置SO_SNDBUFSO_RECVBUF的參數值爲0來實現的。

Int opt  = 0;

//設置發送

setsockopt( serversocket, SOL_SOCKET, SO_SNDBUF,(const char*) &opt, sizeof(opt));

  //設置接收

setsockopt( serversocket, SOL_SOCKET, SO_RECVBUF,(const char*) &opt, sizeof(opt));

 

 組播技術

       internet的某些應用中,有時候需要大量用戶相互協作,若協作規模比較小,可以採用單播通信方式,直接點對點,單點對點得缺點是不管是信息的發送方還是接收方,都需要維護一個用戶列表,代價比較高,有時候也可以採用廣播通信方式,但如果是在擁有數十萬個節點得網絡中,使用廣播會很低效,甚至不可能,因爲此時大多數得主機對此信息可能不感興趣。

因此需要一種折中得辦法,既能實現小組範圍內得互聯,又能高校運轉,爲此,組播就應運而生。

 

224.0.0.1

      編程流程:

  1、套接字基本屬性

   IP_ADD_MEMBERSHIP

   若要加入一個組播組,則要在setsockopt()中設置該選項,其中有一個重要的結構體:

struct ip_mreq

{

struct in_addr imr_multiaddr; //指定組播組的地址

struct in_addr imr_interface;  // 指定接口得IPV4地址

};

   IP_DROP_MEMBERSHIP

   用來從某個組播組中退出

   IP_MULTICAST_IF

   該選項可以修改網絡接口,在結構體ip_mreq中定義新的接口

   IP_MULTICAST_TTL

   該選項用於設置組播報文的數據包的TTL(生存時間),默認值是1,表示數據包只能在本地的子網中傳送。

   IP_MULTICAST_LOOP

    該選項表示組播組中的成員自已也會收到它向本組發送的報文。

2、組播工作流程

      服務器:

      struct sockaddr_in address;

memset(&address, 0 , sizeof(address));

address . sin_family = AF_INET;

address . sin_port = htons(8888);

address . sin_addr . s_addr = inet_addr(“224.0.0.1”);

 

       客戶端:

    //在同一個主機上進行組播設置套接口

   bind(sockCli,(struct sockaddr*)&addrSer,sizeof(addrSer));

    struct ip_mreq multiaddress;

    multiaddress . imr_multiaddr.s_addr = inet_addr(“224.0.0.1”); in_addr

    multiaddress . imr_interface . s_addr = htonl(INADDR_ANY);

    //加入組播組

    if ( setsockopt ( client_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &multiaddress , sizeof (multiaddress))  < 0)

    {

printf(.......)

return 0;

}

   //結束時退出組播組

    if ( setsockopt ( client_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, &multiaddress , sizeof    (multiaddress))  < 0)

    {

printf(.......)

return 0;

}

socket(AF_INET,SOKC_STREAM\SOCK_DGRAM\SOCK_RAW)

原始套接字

     原始套接字是一種套接字底層技術,它工作在網絡層,利用原始套接字可以完成以下功能:

      1、設置網卡爲混雜模式,嗅探當前網絡流經本網卡得所有數據包

      2、構造各種數據包(IPICMPTCPUDP),並進行發送

      3、進行新協議得驗證

原始套接字的創建:

//創建可以獲得所有IP層得數據報文的套接字

     int rawsock = socket(AF_INET, SOCK_RAW, htons(ETH_P_IP));

               協議碼                               協議名

          IPPROTO_ICMP                   ICMP   協議

          ETH_P_IP                             IP         協議

          IPPROTO_TCP                     TCP      協議

          IPPROTO_UDP                     UDP     協議

 

發佈了57 篇原創文章 · 獲贊 32 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章