Winsock错误10022在听
winsock error 10022 in listen
这是我在这个很棒的网站中的第一个问题。
我正在编写一个简单的服务器,获取用户的端口号:
#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");
}
...
};
相关文章:
- 如何在没有侦听器的情况下创建 TCP 连接?
- 在 Linux 上C++:在作为 systemd 服务运行时侦听键盘输入
- Windows 2012 R2 closesocket()挂在侦听套接字上
- 如何使用 ZeroMQ 在特定端口上监听和解析 UDP 数据?
- Winsock错误10022在听
- 提升 MPI 在侦听列表时不释放资源?
- 在自制的C / C++ websocket实现中侦听消息
- Qtcpserver 仅在调试器下在侦听函数上返回未知错误
- 更改 Qt 中不在主线程上的侦听端口
- 在我的应用程序中侦听 iexplorer 的关闭事件
- C++ 套接字侦听器 accept() 在发布时不接受连接请求
- 是否可以在Windows上侦听"ipconfig"更改?
- C 中的远程过程调用(RPC):在硬编码端点时,可以多个客户端侦听一台服务器
- QT QTcpServer in thread;如何在退出时关闭侦听服务器
- 在XInput事件期间要侦听的事件
- 无法再连接到仍在被进程侦听的本地端口
- 当主循环正在侦听消息时,如何在特定时间退出程序
- ASIO :服务器如何在侦听客户端的同时主动向客户端发送信息
- 在 C/Unix 中的 IP 子网上侦听的套接字
- 为什么在 Windows 7 中调用 Beep 函数后我听不到任何声音?