setsockopt返回-1:errno设置为0

时间:2019-01-14 17:29:53

标签: c++ c networking

我是网络编程的新手,并且从A Simple Stream Server中的http://beej.us/guide/bgnet/html/multi/clientserver.html#figure2重写了Visual Studio 2015。在这里,我仅发布部分代码(直到freeaddrinfo(servinfo)),因为该问题已经存在。

// StreamServer.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <errno.h>

#include <string>
#include <sys/types.h>

#include "WinSock2.h"
#include "ws2ipdef.h"
#include "WS2tcpip.h"

#define PORT "3490" // the port users will be connecting to
#define BACKLOG 10  // how many pending connections queue will hold

// get sockaddr, IPv4 or IPv6:
void* get_in_addr(struct sockaddr* sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main()
{
    WSAData wsaData;

    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
        std::cout << "WSAStartup failed." << std::endl;
        exit(1);
    }

    int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;
    int yes = 1;
    char s[INET6_ADDRSTRLEN];
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) == -1) {
        return 1;
    }

    // loop through all the results and bind to the first we can
    for (p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol) == -1)) {
            perror("server: socket");
            continue;
        }

        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)) == -1) {
            perror("setsockopt");
            exit(1);
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            closesocket(sockfd);
            perror("server: bind");
            continue;
        }
        break;
    }

    freeaddrinfo(servinfo);

    WSACleanup();
    return 0;
}

setsockopt(...)失败,并将errno变量设置为0。我还打印了错误,并显示No error。我不明白我做错了什么。我以为程序应该已经在指定的端口上运行并等待,直到某些客户端将数据发送到该端口。

1 个答案:

答案 0 :(得分:1)

你有点混用习惯。

perror来自Linux(或更广泛地说,与POSIX兼容的系统)上的编程,并且会告诉您errno是什么。

但是Windows不使用errno!要从Windows套接字函数获取错误,您需要WSAGetLastError()。那应该告诉您您做错了什么(在这种情况下,为SO_REUSEADDR传递了错误的参数)。