setsockopt возвращает -1: errno установлен в 0 - PullRequest
0 голосов
/ 14 января 2019

Я новичок в сетевом программировании и переписал 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 голосов
/ 15 января 2019

Вы как бы смешиваете идиомы.

perror происходит от программирования на Linux (или, в более широком смысле, на POSIX-совместимых системах) и скажет вам, что такое errno.

Но Windows не использует errno! Чтобы получить ошибку от функции сокетов Windows, вам понадобится WSAGetLastError(). Это должно сказать вам, что вы сделали неправильно (в этом случае, передав неправильный тип аргумента для SO_REUSEADDR).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...