套接口選項

使用setsockopt和getsockopt函數可以設置或讀取套接字接口的選項值

  1. int setsockopt( 
  2.   __in          SOCKET s, 
  3.   __in          int level, 
  4.   __in          int optname, 
  5.   __in          const char* optval, 
  6.   __in          int optlen 
  7. ); 

  1. int getsockopt( 
  2.   __in          SOCKET s, 
  3.   __in          int level, 
  4.   __in          int optname, 
  5.   __out         char* optval, 
  6.   __in_out      int* optlen 
  7. ); 

s是我們感興趣的套接字。level是套接字選項級別。optname是用戶指定的選項名稱。optval是一個指向變量的指針,它的大小有optlen指定,通過optval可以設置或讀取指定的選項的值。

如果沒有錯誤發生,函數返回0,否則返回SOCKET_ERROR。

套接字選項主要有兩種類型:布爾型,用於啓用或禁止套接字的某個屬性;選項參數,整形或者結構體,這隻特定的值。爲了啓動某個布爾型選項,optval應指向某個非零整數,若要禁用則指向一個零值整數,同時,optlen參數值應該等於布爾型大小,即sizeof(BOOL);對其他選項類型,optval應指向整形或者結構體,optlen這爲整型或結構體的大小。

Winsock支持的全部選項級別有IPPROTO_IP,IPPROTO_IPV6,IPPROTO_RM,IPPROTO_TCP,IPPROTO_UDP,NSPROTO_IPX,

SOL_AOOLETALK,SOL_IRLMP,SOL_SOCKET

---

//一些列類型說明

---

以SO_RCVTIMEO爲例說明SOL_SOCKET選項的使用。下面例子演示如何爲TCP/IP套接字設置並讀取接收超時值,(希望能在10秒內收到對方主動發來的數據):

  1. #include<stdio.h> 
  2. #include<winsock2.h> 
  3. #pragma comment(lib,"ws2_32.lib") 
  4.  
  5. #define TCP 
  6.  
  7. void HandleError(char *); 
  8.  
  9. int main() 
  10.     WSADATA wsaData; 
  11.     WSAStartup(MAKEWORD(2,2), &wsaData); 
  12.     DWORD begin, finish; 
  13.      
  14.     struct timeval tv; 
  15.     tv.tv_sec = 10000; 
  16.     tv.tv_usec = 0; 
  17.     int optlen = sizeof(tv); 
  18.      
  19. #ifdef TCP 
  20.     SOCKET sock = socket(AF_INET,SOCK_STREAM,0); 
  21.     printf("TCP test\n"); 
  22.     SOCKADDR_IN to; 
  23.     memset(&to,0,sizeof(SOCKADDR_IN)); 
  24.     to.sin_family = AF_INET; 
  25.     to.sin_port = htons(5050); 
  26.     to.sin_addr.s_addr = inet_addr("202.119.24.32"); 
  27.     if(SOCKET_ERROR==connect(sock,(SOCKADDR*)&to,sizeof(SOCKADDR_IN))) 
  28.     { 
  29.         HandleError("connect"); 
  30.         closesocket(sock); 
  31.         WSACleanup(); 
  32.         return -1; 
  33.     } 
  34.     if(SOCKET_ERROR==setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO, 
  35.                                 (char*)&tv,optlen)) 
  36.     { 
  37.         HandleError("setsockopt"); 
  38.         closesocket(sock); 
  39.         WSACleanup(); 
  40.         return -1; 
  41.     } 
  42.     char buf[100]; 
  43.     begin = GetTickCount(); 
  44.     if(SOCKET_ERROR==recv(sock,buf,100,0)) 
  45.     { 
  46.         HandleError("recv"); 
  47.         if(WSAETIMEDOUT==WSAGetLastError()) 
  48.         { 
  49.             printf("WSAETIMEDOUT\n"); 
  50.         } 
  51.     } 
  52.     finish = GetTickCount(); 
  53. #else //UDP 
  54.     SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); 
  55.     printf("UDP test\n"); 
  56.     SOCKADDR_IN local; 
  57.     memset(&local,0,sizeof(SOCKADDR_IN)); 
  58.     local.sin_family=AF_INET; 
  59.     local.sin_port=htons(5050); 
  60.     local.sin_addr.s_addr=INADDR_ANY; 
  61.     if(SOCKET_ERROR==bind(sock,(SOCKADDR*)&local,sizeof(SOCKADDR_IN))) 
  62.     { 
  63.         HandleError("bind"); 
  64.         closesocket(sock); 
  65.         WSACleanup(); 
  66.         return -1; 
  67.     } 
  68.     if(SOCKET_ERROR==setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO, 
  69.                                 (char*)&tv,optlen)) 
  70.     { 
  71.         HandleError("setsockopt"); 
  72.         closesocket(sock); 
  73.         WSACleanup(); 
  74.         return -1; 
  75.     } 
  76.     char buf[100]; 
  77.     begin = GetTickCount(); 
  78.     if(SOCKET_ERROR==recvfrom(sock,buf,100,0,NULL,NULL)) 
  79.     { 
  80.         HandleError("recvfrom"); 
  81.         if(WSAETIMEDOUT==WSAGetLastError()) 
  82.         { 
  83.             printf("WSAETIMEDOUT\n"); 
  84.         } 
  85.     } 
  86.     finish = GetTickCount(); 
  87. #endif 
  88.     printf("實際等待時間(毫秒):%d\n", finish-begin); 
  89.     memset(&tv,0,optlen); 
  90.     if(SOCKET_ERROR==getsockopt(sock,SOL_SOCKET,SO_RCVTIMEO, 
  91.                                 (char*)&tv,&optlen)) 
  92.     { 
  93.         HandleError("getsockopt"); 
  94.     } 
  95.     printf("設置等待時間(毫秒):%d\n", tv.tv_sec); 
  96.     closesocket(sock); 
  97.     WSACleanup(); 
  98.     return 0; 
  99.  
  100. void HandleError(char* func) 
  101.     int errCode = WSAGetLastError(); 
  102.     char info[65] = {0}; 
  103.     _snprintf(info,64,"%s:   %d", func,errCode); 
  104.     printf(info); 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章