#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); Теперь будет вызываться нужная функция. Выводы Если функция что-то возвращает, всегда проверяйте результат. И все будет хорошо.
Комментариев нет:
Отправить комментарий