C++ - Windows - recvfrom() 在简单服务器上因 "No such file or directory" 失败
C++ - Windows - recvfrom() failing with "No such file or directory" on simple server
这是我正在尝试制作的非常简单的服务器的代码:
Network.h:
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <system_error>
#include <string>
#include <iostream>
#pragma once
class WSASession
{
public:
WSASession()
{
int ret = WSAStartup(MAKEWORD(2, 2), &data);
if (ret != 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "WSAStartup Failed");
}
~WSASession()
{
WSACleanup();
}
private:
WSAData data;
};
class UDPSocket
{
public:
UDPSocket()
{
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
throw std::system_error(WSAGetLastError(), std::system_category(), "Error opening socket");
}
~UDPSocket()
{
closesocket(sock);
}
void SendTo(const std::string& address, unsigned short port, const char* buffer, int len, int flags = 0)
{
sockaddr_in add;
add.sin_family = AF_INET;
add.sin_addr.s_addr = inet_addr(address.c_str());
add.sin_port = htons(port);
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&add), sizeof(add));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
}
void SendTo(sockaddr_in& address, const char* buffer, int len, int flags = 0)
{
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&address), sizeof(address));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
}
sockaddr_in RecvFrom(char* buffer, int len, int flags = 0)
{
sockaddr_in from;
int size = sizeof(from);
int ret = recvfrom(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&from), &size);
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "recvfrom failed");
// make the buffer zero terminated
buffer[ret] = 0;
return from;
}
void Bind(unsigned short port)
{
sockaddr_in add;
add.sin_family = AF_INET;
add.sin_addr.s_addr = htonl(INADDR_ANY);
add.sin_port = htons(port);
int ret = bind(sock, reinterpret_cast<SOCKADDR *>(&add), sizeof(add));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "Bind failed");
}
private:
SOCKET sock;
};
监听器服务器:
try
{
WSASession Session;
UDPSocket Socket;
char buffer[512];
Socket.Bind(22);
while (1)
{
sockaddr_in add = Socket.RecvFrom(buffer, sizeof(buffer));
std::string srecv(buffer);
}
}
catch (std::system_error& e)
{
std::cout << e.what();
}
在接受来自客户端的连接之前,一切都是完美的。 recvfrom 函数失败并出现错误 "No such file or directory"
有人看到问题了吗?我知道该端口没有问题,因为我正在从一个运行良好的 .net 应用程序监听同一个端口。
你有:
const std::string& address, unsigned short port, const char* buffer, int len, int flags = 0)
和
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&add)
演员阵容无效。 std::string
不是 SOCKADDR
。你必须 convert, 可能通过调用 getaddrinfo()
.
这是我正在尝试制作的非常简单的服务器的代码:
Network.h:
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <system_error>
#include <string>
#include <iostream>
#pragma once
class WSASession
{
public:
WSASession()
{
int ret = WSAStartup(MAKEWORD(2, 2), &data);
if (ret != 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "WSAStartup Failed");
}
~WSASession()
{
WSACleanup();
}
private:
WSAData data;
};
class UDPSocket
{
public:
UDPSocket()
{
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
throw std::system_error(WSAGetLastError(), std::system_category(), "Error opening socket");
}
~UDPSocket()
{
closesocket(sock);
}
void SendTo(const std::string& address, unsigned short port, const char* buffer, int len, int flags = 0)
{
sockaddr_in add;
add.sin_family = AF_INET;
add.sin_addr.s_addr = inet_addr(address.c_str());
add.sin_port = htons(port);
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&add), sizeof(add));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
}
void SendTo(sockaddr_in& address, const char* buffer, int len, int flags = 0)
{
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&address), sizeof(address));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
}
sockaddr_in RecvFrom(char* buffer, int len, int flags = 0)
{
sockaddr_in from;
int size = sizeof(from);
int ret = recvfrom(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&from), &size);
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "recvfrom failed");
// make the buffer zero terminated
buffer[ret] = 0;
return from;
}
void Bind(unsigned short port)
{
sockaddr_in add;
add.sin_family = AF_INET;
add.sin_addr.s_addr = htonl(INADDR_ANY);
add.sin_port = htons(port);
int ret = bind(sock, reinterpret_cast<SOCKADDR *>(&add), sizeof(add));
if (ret < 0)
throw std::system_error(WSAGetLastError(), std::system_category(), "Bind failed");
}
private:
SOCKET sock;
};
监听器服务器:
try
{
WSASession Session;
UDPSocket Socket;
char buffer[512];
Socket.Bind(22);
while (1)
{
sockaddr_in add = Socket.RecvFrom(buffer, sizeof(buffer));
std::string srecv(buffer);
}
}
catch (std::system_error& e)
{
std::cout << e.what();
}
在接受来自客户端的连接之前,一切都是完美的。 recvfrom 函数失败并出现错误 "No such file or directory"
有人看到问题了吗?我知道该端口没有问题,因为我正在从一个运行良好的 .net 应用程序监听同一个端口。
你有:
const std::string& address, unsigned short port, const char* buffer, int len, int flags = 0)
和
int ret = sendto(sock, buffer, len, flags, reinterpret_cast<SOCKADDR *>(&add)
演员阵容无效。 std::string
不是 SOCKADDR
。你必须 convert, 可能通过调用 getaddrinfo()
.