Winsock错误10022在听

winsock error 10022 in listen

本文关键字:在听 10022 错误 Winsock      更新时间:2023-10-16

这是我在这个很棒的网站中的第一个问题。

我正在编写一个简单的服务器,获取用户的端口号:

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>
#include <cstring>
class socketConexion { 
private: 
    WSADATA wsaData; 
    int iResultado; 
    SOCKET socketServidor = INVALID_SOCKET;  socket servidor 
    SOCKET socketCliente = INVALID_SOCKET; 
    struct sockaddr *clienteSockaddr;
    struct addrinfo *socketResultado = NULL;
    struct addrinfo datosServidor;
    std::string puertoUsuario;
    char clienteIPV4[LONG_IPV4];
public:
    int iniciarWinsock () { 
        iResultado = WSAStartup(MAKEWORD(2,2), &wsaData);
        printf ("Inicializando Winsock2 n");
        if (iResultado != 0) { 
            printf ("Error al iniciar Winsock2: %dn", iResultado);
            return 1;
        else {
            printf ("Winsock2 Inicializadon");
            return 0;
        }
    }
    int obtenerDirServidor () {
        printf ("Introduzca puerto: ");
        std::cin >> puertoUsuario;
        printf ("Obteniendo datos de servidor.n");
        ZeroMemory(&datosServidor, sizeof(datosServidor));
        datosServidor.ai_family = AF_INET;
        datosServidor.ai_socktype = SOCK_STREAM;
        datosServidor.ai_protocol = IPPROTO_TCP;
        datosServidor.ai_flags = AI_PASSIVE;
        iResultado = getaddrinfo(NULL, (const char*)puertoUsuario.c_str(), &datosServidor, &socketResultado);
        if (iResultado != 0) {
            printf ("Error al obtener dirección de servidor: %dn", iResultado);
            WSACleanup();
            return 1;
        }
        else {
            printf ("Dirección de servidor obtenida.n");
            return 0;
        }
    }
    int socketBind () {
        socketServidor = socket(socketResultado->ai_family, socketResultado->ai_socktype, socketResultado->ai_protocol);
        if (socketServidor == INVALID_SOCKET) {
            printf ("Error al crear socket: %dn", WSAGetLastError ());
            freeaddrinfo (socketResultado);
            WSACleanup();
            return 1;
        }
        else {
            printf ("Socket creado correctamente.n");
            return 0;
        }
        iResultado = bind(socketServidor, socketResultado->ai_addr, (int)socketResultado->ai_addrlen);
        if (iResultado == SOCKET_ERROR) {
            printf ("Error al direccionar socket: %dn", WSAGetLastError());
            freeaddrinfo (socketResultado);
            closesocket(socketServidor);
            WSACleanup();
            return 1;
        }
        else {
            printf ("Socket direccionado correctamente. n");
            return 0;   
        }
        freeaddrinfo (socketResultado);
    }
    int socketListen (){
        iResultado = listen(socketServidor, SOMAXCONN);
        if (iResultado == SOCKET_ERROR) {
            printf ("Error al poner socket a la escucha socket: %dn", WSAGetLastError());
            closesocket(socketServidor);
            WSACleanup();
            return 1;
        }
        else {
            printf ("Esperando conexión..... %dn");
            return 0;
        }
         .....

我在调用收听函数时会收到错误10022,我看不到无效的参数我传递给函数。

错误代码10022是 WSAEINVAL

无效的参数。
提供了一些无效的参数(例如,将无效级别指定到setsockopt函数(。在某些情况下,它也指插座的当前状态 - 例如,在不侦听的套接字上调用accept

根据listen()文档:

返回值

如果没有发生错误,则listen返回零。否则,返回SOCKET_ERROR的值,可以通过调用WSAGetLastError

来检索特定的错误代码。

...

wsaeinval
插座尚未与bind

绑定

在您的socketBind()方法中,如果socket()成功,则在调用bind()之前调用return,因此插座永远不会绑定。您需要在1st else块中删除return语句。另外,如果bind()成功,第二个else块在调用freeaddrinfo()之前调用return,因此您也需要解决此问题。

尝试以下操作:

int socketBind () {
    socketServidor = socket(socketResultado->ai_family, socketResultado->ai_socktype, socketResultado->ai_protocol);
    if (socketServidor == INVALID_SOCKET) {
        printf ("Error al crear socket: %dn", WSAGetLastError ());
        freeaddrinfo (socketResultado);
        WSACleanup();
        return 1;
    }
    printf ("Socket creado correctamente.n");
    iResultado = bind(socketServidor, socketResultado->ai_addr, (int)socketResultado->ai_addrlen);
    if (iResultado == SOCKET_ERROR) {
        printf ("Error al direccionar socket: %dn", WSAGetLastError());
        freeaddrinfo (socketResultado);
        closesocket(socketServidor);
        WSACleanup();
        return 1;
    }
    printf ("Socket direccionado correctamente. n");
    freeaddrinfo (socketResultado);
    return 0;   
}

话虽如此,您的班级总体上做得不好。我建议一些c - 喜欢(使用raii,在错误上抛出例外等(:

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>
#include <system_error>  
#include <memory>
class socketError : public std::system_error
{
public:
    explicit socketError(int err, const std::string &msg)
        : std::system_error(err, std::system_category(), msg + ": " + std::to_string(err))
    {
    }
};
void throwSocketError(int err, const std::string &msg)
{
    std::cout << msg << ": " << err << std::endl;
    throw socketError(err, msg);
}
class wsaInit
{
public:
    wsaInit() {
        int iResultado = WSAStartup(MAKEWORD(2,2), &wsaData);
        printf ("Inicializando Winsock2 n");
        if (iResultado != 0)
            throwSocketError(iResultado, "Error al iniciar Winsock2");
        printf ("Winsock2 Inicializadon");
    }
    ~wsaInit() {
        WSACleanup();
    }
    wsaInit(const wsaInit &) = delete;
    wsaInit& operator=(const wsaInit &) = delete;
};
class socketWrapper
{
private:
    SOCKET sckt;
public:
    socketWrapper() : sckt(INVALID_SOCKET) {}
    explicit socketWrapper(SOCKET initialSocket) : sckt(initialSocket) {}
    ~socketWrapper() { reset(); }
    socketWrapper(const socketWrapper &) = delete; 
    socketWrapper& operator=(const socketWrapper &) = delete; 
    void reset(SOCKET newSocket = INVALID_SOCKET) { if (sckt != INVALID_SOCKET) closesocket(sckt); sckt = newSocket; }
    operator SOCKET() const { return sckt; }
    bool operator !() const { return (sckt == INVALID_SOCKET); }
};
class socketConexion { 
private: 
    wsaInit wsa; 
    socketWrapper socketServidor;
    socketWrapper socketCliente; 
    std::unique_ptr<struct addrinfo> socketResultado;
    ...
public:
    socketConexion(const socketConexion &) = delete; 
    socketConexion& operator=(const socketConexion &) = delete; 
    void obtenerDirServidor() {
        socketResultado.reset();
        printf ("Introduzca puerto: ");
        std::string puertoUsuario;
        std::cin >> puertoUsuario;
        printf ("Obteniendo datos de servidor.n");
        struct addrinfo datosServidor;
        ZeroMemory(&datosServidor, sizeof(datosServidor));
        datosServidor.ai_family = AF_INET;
        datosServidor.ai_socktype = SOCK_STREAM;
        datosServidor.ai_protocol = IPPROTO_TCP;
        datosServidor.ai_flags = AI_PASSIVE;
        struct addrinfo *pResultado;
        int iResultado = getaddrinfo(NULL, puertoUsuario.c_str(), &datosServidor, &pResultado);
        if (iResultado != 0)
            throwSocketError(iResultado, "Error al obtener dirección de servidor");
        socketResultado.reset(pResultado);
        std::cout << "Dirección de servidor obtenida." << std::endl;
    }
    void socketBind () {
        socketServidor.reset();
        if (!socketResultado)
            obtenerDirServidor();
        socketServidor.reset(socketResultado->ai_family, socketResultado->ai_socktype, socketResultado->ai_protocol));
        if (!socketServidor) {
            int iError = WSAGetLastError();
            socketResultado.reset();
            throwSocketError(iError, "Error al crear socket");
        }
        printf("Socket creado correctamente.n");
        int iResultado = ::bind(socketServidor, socketResultado->ai_addr, (int)socketResultado->ai_addrlen);
        if (iResultado == SOCKET_ERROR) {
            iResultado = WSAGetLastError();
            socketResultado.reset();
            throwSocketError(iResultado, "Error al direccionar socket");
        }
        socketResultado.reset();
        printf ("Socket direccionado correctamente. n");
    }
    void socketListen() {
        if (!socketServidor)
            socketBind();
        int iResultado = listen(socketServidor, SOMAXCONN);
        if (iResultado == SOCKET_ERROR)
            throwSocketError(WSAGetLastError(), "Error al poner socket a la escucha socket");
        printf ("Esperando conexión.....n");
    }
    ...
};