Собираю маленький игровой сервер и никак не мог понять, почему он иногда не работает, почти один и тот же код в разных проектах. И вот методом скурпулезного выколупывания вычислил, что если закоментить <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;
}
Пролог
В целом, я разобрался с сим безобразием. Нашел рабочую студию и потестил, минут 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);
Теперь будет вызываться нужная функция.
Выводы
Если функция что-то возвращает, всегда проверяйте результат. И все будет хорошо.
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Хотелось бы самому написать небольшой скрипт поиска по БДВсе это хорошо реализовать с помощью LIKE %abc%, но как быть с релевантностью? Чтобы...