Страницы

Поиск по вопросам

Показаны сообщения с ярлыком winsock. Показать все сообщения
Показаны сообщения с ярлыком winsock. Показать все сообщения

вторник, 7 апреля 2020 г.

удаление SOCKET из памяти

#cpp #winsock

                    
#include 
#pragma comment(lib, "ws2_32.lib" )

void main(){

    WSADATA buff;
    WSAStartup(0x202, &buff);
    SOCKET S;

    while (1){
        S = ::socket(AF_INET, SOCK_STREAM, 0);
        closesocket(S);
    }
}


При работе память в диспетчере все растет и растет, как исправить?
    


Ответы

Ответ 1



В данном случае сбоил socket модуль, помогло netsh winsock reset

пятница, 28 февраля 2020 г.

Ошибка при вызове WSAPoll()

#cpp #c #winapi #клиент_сервер #winsock


Пишу простой UDP сервер под Windows, который принимает сообщения от клиентов. По
заданию сокеты должны работать в неблокирующем режиме и обязательно нужно использовать
WSAPoll для параллельного обслуживания клиентов. Написал небольшую обертку для сокета:

class _socket
{
private:
    SOCKET      sock;
    sockaddr_in addr;
public:
    _socket(int port);
    _socket(const _socket & other);
    ~_socket();

    SOCKET GetSocket();
    bool   Generate();
    bool   Bind();
};

_socket::~_socket() 
{
    if (sock != INVALID_SOCKET) 
    {
        closesocket(sock); 
    } 
}

_socket::_socket(int port) : sock(INVALID_SOCKET) 
{
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
}

_socket::_socket(const _socket & other)
{
    this->sock = other.sock;
    this->addr = other.addr;
}

SOCKET _socket::GetSocket()
{
     return (this->sock); 
}
bool _socket::Generate()
{
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        return false;
    }
    else
    {
        unsigned long mode = 1;
        return (ioctlsocket(sock, FIONBIO, &mode) != SOCKET_ERROR);
    }
}
bool _socket::Bind()
{
    return (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) >= 0);
}


Вот так работаю с ним в main (через argv передаю диапазон портов):

int main(int argc, const char *argv[])
{
    std::vector<_socket>        sockets;
    std::map clients;

    if (argc < 3)
    {
        return ErrorPrint("Too low arguments");
    }
    if (!Init())
    {
        return ErrorPrint("Error starting WSA");
    }

    for (int i = atoi(argv[1]); i <= atoi(argv[2]); i++)
    {
        _socket s(i);
        if (!s.Generate())
        {
            return ErrorPrint("Cannot create socket");
        }
        if (!s.Bind())
        {
            return ErrorPrint("Cannot bind socket");
        }
        sockets.push_back(s);
    }

    WSAPOLLFD *pfd = (WSAPOLLFD*)malloc(sockets.size() * sizeof(WSAPOLLFD));

    for (int i = 0; i < sockets.size(); i++)
    {
        pfd[i].fd      = sockets[i].GetSocket();
        pfd[i].events  = POLLIN | POLLOUT;
        pfd[i].revents = 0;
    }

    while (true)
    {
        int ev_cnt = WSAPoll(pfd, sockets.size(), 1000);
        if (ev_cnt > 0)
        {
            for (int i = 0; i < sockets.size(); i++)
            {
                if (pfd[i].revents & POLLERR)
                {

                }
                if (pfd[i].revents & POLLIN)
                {

                }
                if (pfd[i].revents & POLLOUT)
                {

                }
            }
        }
        else if (ev_cnt == SOCKET_ERROR)
        {
            std::cout << "Error WSAPoll: " << WSAGetLastError() << std::endl; //
Постоянно попадаю сюда
        }
        else
        {
            std::cout << "waiting..." << std::endl;
        }
    }

    return (EXIT_SUCCESS);
}


При вызове WSAPoll постоянно получаю ошибку WSAENOTSOCK (10038), которая говорит
мне, что я пытаюсь выполнить операцию, предназначенную для сокета на чем-то, что им
не является. Прочитал спецификации к WSAPoll - вроде все делаю правильно, никак не
могу понять, что сделал не так.
    


Ответы

Ответ 1



У вас реализован конструктор копирования после выполнения которого в двух экземплярах класса будет хранится один и тот же дескриптор сокета. После разрушения одного из экземпляров второй останется с невалидным дескриптором. Следовало реализовать конструктор перемещения (и перемещающий оператор присваивания): _socket(const _socket & other) = delete; _socket(_socket && other) : sock{other.sock} , addr{other.addr} { other.sock = INVALID_SOCKET; ::std::memset(::std::addressof(other.addr), 0, sizeof(other.addr)); } Сокеты на самом деле можно дублировать используя WSADuplicateSocket, но обычно это не нужно.

пятница, 21 июня 2019 г.

удаление SOCKET из памяти

#include #pragma comment(lib, "ws2_32.lib" )
void main(){
WSADATA buff; WSAStartup(0x202, &buff); SOCKET S;
while (1){ S = ::socket(AF_INET, SOCK_STREAM, 0); closesocket(S); } }
При работе память в диспетчере все растет и растет, как исправить?


Ответ

В данном случае сбоил socket модуль, помогло netsh winsock reset

четверг, 16 мая 2019 г.

Ошибка при вызове WSAPoll()

Пишу простой UDP сервер под Windows, который принимает сообщения от клиентов. По заданию сокеты должны работать в неблокирующем режиме и обязательно нужно использовать WSAPoll для параллельного обслуживания клиентов. Написал небольшую обертку для сокета:
class _socket { private: SOCKET sock; sockaddr_in addr; public: _socket(int port); _socket(const _socket & other); ~_socket();
SOCKET GetSocket(); bool Generate(); bool Bind(); };
_socket::~_socket() { if (sock != INVALID_SOCKET) { closesocket(sock); } }
_socket::_socket(int port) : sock(INVALID_SOCKET) { memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); }
_socket::_socket(const _socket & other) { this->sock = other.sock; this->addr = other.addr; }
SOCKET _socket::GetSocket() { return (this->sock); } bool _socket::Generate() { sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { return false; } else { unsigned long mode = 1; return (ioctlsocket(sock, FIONBIO, &mode) != SOCKET_ERROR); } } bool _socket::Bind() { return (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) >= 0); }
Вот так работаю с ним в main (через argv передаю диапазон портов):
int main(int argc, const char *argv[]) { std::vector<_socket> sockets; std::map clients;
if (argc < 3) { return ErrorPrint("Too low arguments"); } if (!Init()) { return ErrorPrint("Error starting WSA"); }
for (int i = atoi(argv[1]); i <= atoi(argv[2]); i++) { _socket s(i); if (!s.Generate()) { return ErrorPrint("Cannot create socket"); } if (!s.Bind()) { return ErrorPrint("Cannot bind socket"); } sockets.push_back(s); }
WSAPOLLFD *pfd = (WSAPOLLFD*)malloc(sockets.size() * sizeof(WSAPOLLFD));
for (int i = 0; i < sockets.size(); i++) { pfd[i].fd = sockets[i].GetSocket(); pfd[i].events = POLLIN | POLLOUT; pfd[i].revents = 0; }
while (true) { int ev_cnt = WSAPoll(pfd, sockets.size(), 1000); if (ev_cnt > 0) { for (int i = 0; i < sockets.size(); i++) { if (pfd[i].revents & POLLERR) {
} if (pfd[i].revents & POLLIN) {
} if (pfd[i].revents & POLLOUT) {
} } } else if (ev_cnt == SOCKET_ERROR) { std::cout << "Error WSAPoll: " << WSAGetLastError() << std::endl; // Постоянно попадаю сюда } else { std::cout << "waiting..." << std::endl; } }
return (EXIT_SUCCESS); }
При вызове WSAPoll постоянно получаю ошибку WSAENOTSOCK (10038), которая говорит мне, что я пытаюсь выполнить операцию, предназначенную для сокета на чем-то, что им не является. Прочитал спецификации к WSAPoll - вроде все делаю правильно, никак не могу понять, что сделал не так.


Ответ

У вас реализован конструктор копирования после выполнения которого в двух экземплярах класса будет хранится один и тот же дескриптор сокета. После разрушения одного из экземпляров второй останется с невалидным дескриптором. Следовало реализовать конструктор перемещения (и перемещающий оператор присваивания):
_socket(const _socket & other) = delete;
_socket(_socket && other) : sock{other.sock} , addr{other.addr} { other.sock = INVALID_SOCKET; ::std::memset(::std::addressof(other.addr), 0, sizeof(other.addr)); }
Сокеты на самом деле можно дублировать используя WSADuplicateSocket, но обычно это не нужно.