【问题标题】:Why does getsockopt return an error?为什么getsockopt返回错误?
【发布时间】:2017-09-01 12:32:03
【问题描述】:

我在 Windows 上遇到了一个套接字问题。调用 getsockopt() 总是失败。奇怪的是 setsockopt() 似乎工作(至少它报告成功......虽然我设置的选项似乎没有我期望的效果)。

我的代码如下。运行它会报告成功的 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;
            }
        }

【问题讨论】:

    标签: c windows sockets


    【解决方案1】:

    getsockopt 的最后一个参数是一个指针,而不是 size_t。

    documentation 中的注释 getsockopt 被声明为:

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

    您需要初始化一个大小为 optval 的 int,并将指向该 int 的指针作为最后一个参数传递。将您的代码更改为:

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

    【讨论】:

    • 噢!谢谢...我知道这很简单。
    • 我认为这是一个编译器错误。您不应该能够将任何整数(包括sizeof())传递给没有类型转换的指针。该规则的唯一例外是文字0。因此,对于 getsockopt()sizeof(ling) 作为直接输入进行编译,这意味着在将整数而不是指针作为输入的范围内可能存在 getsockopt() 的第 3 方重载。
    • 这不是编译器错误,编译器可能确实发出了警告,但它不被视为错误。 (问题标记为 C,在 C++ 中无法编译)
    猜你喜欢
    • 2014-11-17
    • 2021-01-05
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多