2017-09-01 4 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ではなくポインタです。 documentationから

getsockoptは次のように宣言されていること:あなたがoptvalのサイズとint型をinitalizeし、最後の引数としてそのint型へのポインタを渡す必要があり

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

。コードを次のように変更してください。

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

関連する問題