2017-09-01 178 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

相关问题