2017-09-01 130 views
2

我在Windows上遇到了套接字問題。調用getsockopt()總是失敗。奇怪的是,setsockopt()似乎工作(至少它報告成功......雖然我設置的選項似乎沒有我期望的效果)。爲什麼getsockopt返回一個錯誤?

我的代碼如下。運行它會報告成功的setsockopt調用,但getsockopt會因WSAEFAULT失敗。我究竟做錯了什麼?

 struct linger ling; 

     ... 

     ling.l_onoff = 1; 
     ling.l_linger = 10; 
     if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) == SOCKET_ERROR) { 
      fprintf(stderr, "******** setsockopt failed\n"); 
      ret = -1; 
      break; 
     } else { 
      fprintf(stderr, "******** setsockopt success\n"); 
     } 
     if (getsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) == SOCKET_ERROR) { 
      fprintf(stderr, "****** failed getting sockopt\n"); 
      switch(WSAGetLastError()) { 
       case WSANOTINITIALISED: 
        fprintf(stderr, "******WSANOTINITIALISED\n"); 
        break; 
       case WSAENETDOWN: 
        fprintf(stderr, "******WSAENETDOWN\n"); 
        break; 
       case WSAEFAULT: 
        fprintf(stderr, "******WSAEFAULT\n"); 
        break; 
       case WSAEINPROGRESS: 
        fprintf(stderr, "******WSAEINPROGRESS\n"); 
        break; 
       case WSAEINVAL: 
        fprintf(stderr, "******WSAEINVAL\n"); 
        break; 
       case WSAENOPROTOOPT: 
        fprintf(stderr, "******WSAENOPROTOOPT\n"); 
        break; 
       case WSAENOTSOCK: 
        fprintf(stderr, "******WSAENOTSOCK\n"); 
        break; 
       default: 
        fprintf(stderr, "******Unknown error %d\n", ret); 
        break; 
      } 
     } 

回答

4

getsockopt的最後一個參數是一個指針,而不是size_t。

int getsockopt(
    _In_ SOCKET s, 
    _In_ int level, 
    _In_ int optname, 
    _Out_ char *optval, 
    _Inout_ int *optlen 
); 

您需要initalize與optval大小的int和指針傳遞給INT作爲最後一個參數:從documentation

注意,如getsockopt聲明。將您的代碼更改爲:

int slen; 
.. 
slen = sizeof ling; 
getsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, &slen) 
+0

Doh!謝謝......我知道這很簡單。 –

+0

我會認爲這是一個編譯器錯誤。您不應該能夠將任何整數(包括'sizeof()')傳遞給沒有類型轉換的指針。該規則的唯一例外是一個文字'0'。因此,對於'getsockopt()'用'sizeof(ling)'作爲直接輸入進行編譯,這意味着可能有第三方重載'getsockopt()'作爲輸入,而不是指針。 –

+0

這不是編譯器錯誤,編譯器可能會這樣做發出警告,但它不被視爲錯誤。 (這個問題被標記爲C,在C++中它不會編譯) – nos

相關問題