Страницы

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

среда, 29 января 2020 г.

Сервер и Thread не уживаются

#cpp #сервер #многопоточность


Собираю маленький игровой сервер и никак не мог понять, почему он иногда не работает,
почти один и тот же код в разных проектах. И вот методом скурпулезного выколупывания
вычислил, что если закоментить , то сервер работает. Кто-нибудь может объяснить
почему? Где конфликт и как с этим бороться?
#define MAX_SLOTS 400
#define _CRT_SECURE_NO_WARNINGS
#include
#include
//#include 
#include
using namespace std;
#pragma comment(lib, "WS2_32.lib")
#pragma comment (lib, "mswsock.lib")

#define PORT 11112
#define SERVER "127.0.0.1"

int main()
{
    setlocale(LC_ALL, "Russian");
    WSAData WSADat; // Свойства WinSock (результат функции WSAStartup)
    WSAStartup(0x0202, &WSADat); // Инициализация WinSock
    SOCKET  Socket;

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (!Socket)cout << "soket no create" << endl;
    sockaddr_in socketAddr;
    socketAddr.sin_family = AF_INET;
    socketAddr.sin_port = htons(PORT);
    socketAddr.sin_addr.s_addr = 0;
    bind(Socket, (struct sockaddr*)&socketAddr, sizeof(socketAddr));
    listen(Socket, SOMAXCONN);

    SOCKET client_socket;
    sockaddr_in clientAddr;
    int client_addr_size = sizeof(clientAddr);

    // цикл извлечения запросов на подключение из очереди

    while ((client_socket = accept(Socket, (sockaddr *)&clientAddr, &client_addr_size)))
    {
        printf("ghghgf");
    }
    WSACleanup();
    return 0;
}
    


Ответы

Ответ 1



Пролог В целом, я разобрался с сим безобразием. Нашел рабочую студию и потестил, минут 15 заняло. :) Настелим соломки В целом да, accept срабатывает, потому что он возвращает -1. WSAGetLastError говорит 10022. Согласно документации это "неверно настроенный сокет, например, пытаемся делать accept на сокете, для которого не сделали listen". Смотрим на listen - он-то вызывается! Но мы-то знаем, что он возвращает -1 в случае ошибки, а ТС не добавил подобных проверок. Добавляем где-то так: int err = listen(Socket, SOMAXCONN); if (err == -1) { int c = WSAGetLastError(); printf("error = %d\n", c); return 1; } Запускаем. Снова 10022. Комментируем #include - все нормально. Интереснее. Страсти накаляются Значит, неверно сработал предыдущий вызов функции для сокета. А это bind. Проделаем с ним подобное listen. И тут ждет засада - код не компилируется!!! Но документация утверждает, что там все нормально - int bind(...). Снова комментируем #include - все работает. Раскомментируем назад. Переходим на функцию bind и жмем F12 (перейти на декларацию функции). Но мы почему-то в модуле functional. Виновник найден Тут все стает на свои места. Файл thread через вложенные include подтянул functional. А в нем действительно есть функция bind. Да, ее параметры не совсем подходят, но компилятор как-то разрулил. Что делать? Просто напишите вызов функции двоеточиями в начале: ::bind(Socket, (struct sockaddr*)&socketAddr, sizeof(socketAddr)); ::listen(Socket, SOMAXCONN); Теперь будет вызываться нужная функция. Выводы Если функция что-то возвращает, всегда проверяйте результат. И все будет хорошо.

Комментариев нет:

Отправить комментарий