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

150
15 декабря 2016, 16:00

Собираю маленький игровой сервер и никак не мог понять, почему он иногда не работает, почти один и тот же код в разных проектах. И вот методом скурпулезного выколупывания вычислил, что если закоментить <thread>, то сервер работает. Кто-нибудь может объяснить почему? Где конфликт и как с этим бороться?

#define MAX_SLOTS 400
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
//#include <process.h>
#include<thread>
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;
}
Answer 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 <thread> - все нормально. Интереснее.

Страсти накаляются

Значит, неверно сработал предыдущий вызов функции для сокета. А это bind. Проделаем с ним подобное listen. И тут ждет засада - код не компилируется!!! Но документация утверждает, что там все нормально - int bind(...). Снова комментируем #include <thread> - все работает. Раскомментируем назад. Переходим на функцию bind и жмем F12 (перейти на декларацию функции). Но мы почему-то в модуле functional.

Виновник найден

Тут все стает на свои места. Файл thread через вложенные include подтянул functional. А в нем действительно есть функция bind. Да, ее параметры не совсем подходят, но компилятор как-то разрулил.

Что делать?

Просто напишите вызов функции двоеточиями в начале:

::bind(Socket, (struct sockaddr*)&socketAddr, sizeof(socketAddr));
::listen(Socket, SOMAXCONN);

Теперь будет вызываться нужная функция.

Выводы

Если функция что-то возвращает, всегда проверяйте результат. И все будет хорошо.

READ ALSO
OpenGl картинка отображается кверху ногами

OpenGl картинка отображается кверху ногами

Здравствуйте! Есть функция для отрисовки картинки:

144
Поиск с учетом релевантности

Поиск с учетом релевантности

Хотелось бы самому написать небольшой скрипт поиска по БДВсе это хорошо реализовать с помощью LIKE %abc%, но как быть с релевантностью? Чтобы...

216
Объединение запросов UPDATE

Объединение запросов UPDATE

Мне нужно объединить два sql update запроса в один

158