Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50

Winsock sellect(), recv()

11.08.2019, 15:41. Показов 2550. Ответов 12

Студворк — интернет-сервис помощи студентам
Я новичок в winsock. Я узнал, что recv() блокирует winsock. Поэтому я захотел использовать select(), чтобы узнать о наличии данных с сокета. Немного порыскав, я нашел статейку: http://rsdn.org/forum/network/3129697.all . Но написанный мой код не работает, не могу понять почему:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int main()
{
    //... инициализация библиотеки, создание сокета (ListenS), связывание сокета с адресом, 
    listen(ListenS,SOMAXCONN);  
    
    SOCKET CN; 
    CN = accept(ListenS, (sockaddr*)&adrr, &sizeofAddr); //принимаем клиента
    
    char msg[MSGSize]; //массив char на 256
    while(1)
    {
        if(WasEvent(ListenS)) //есть ли сообщение( почему то никода не возвращает true)
        {
            std::cout<<"I received msg: ";
            recv(CN, msg, MSGSize, 0); //получаем его
            std::cout<<msg<<std::endl;
        }
    }
    //.. закрытие библиотеки, закрытие сокетов
    return 0;
}
//...
bool WasEvent(SOCKET&sock){ 
    fd_set read_fds; //
    FD_ZERO(&read_fds);
    FD_SET(sock, &read_fds);
 
    timeval timeout;
    timeout.tv_sec=1; // если в течении 1 секунды данных нет, то выходим
    timeout.tv_usec=0;
 
    int result = select(0, &read_fds, NULL, NULL, &timeout);
    if( SOCKET_ERROR == result)
        ErrorExit("SOCKET_ERROR", result); //функция, которая выводит сообщение и выходит из программы(exit)
    if( FD_ISSET(sock, &read_fds) || result != 0 ) //есть данных
        return true;
    return false; //нет данных
}
Почему то, WasEvent работает с определением, есть ли запрашивающие соединения. То есть , если я поставлю код:
C++
1
2
3
4
if(WasEvent(ListenS)) //есть, кто коннектится
{
//создаем сокет соединения : accept ...
}
Я так понимаю, проблема с новым сокетом(CN). Подскажите, как исправить мой код, или альтернативы.
Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.08.2019, 15:41
Ответы с готовыми решениями:

Winsock recv Error
вот код: int Server::RecvData(string&amp; data) { int recv_bytes =0 ; recv_bytes = client_socket_.RecvData(data); return...

WinSock recv для wchar_t
Здравствуйте. Столкнулся с проблемой. Написал небольшое приложение, в котором одно из действий это скачивание страницы. Решил всё немного...

Не могу разобраться с send и recv Winsock
Есть клиент и сервер, инициализация, подключение и тд. работают правильно, но send и recv нет. Клиент - отправляет по очереди 3...

12
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2019, 16:59
Цитата Сообщение от Dimgo2 Посмотреть сообщение
Я новичок в winsock. Я узнал, что recv() блокирует winsock. Поэтому я захотел использовать select(), чтобы узнать о наличии данных с сокета. Немного порыскав, я нашел статейку: http://rsdn.org/forum/network/3129697.all . Но написанный мой код не работает, не могу понять почему:
Потому что для ListenS надо сначала сделать select, а когда он вернёт для него FD_ISSET, вызвать accept.
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
11.08.2019, 20:10  [ТС]
Дело в том, что я хочу это сделать не для принятия соединения, а для осведомления о пришедших данных(после использовать recv()). Но это не работает
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2019, 20:18
Лучший ответ Сообщение было отмечено Dimgo2 как решение

Решение

Цитата Сообщение от Dimgo2 Посмотреть сообщение
Дело в том, что я хочу это сделать не для принятия соединения, а для осведомления о пришедших данных(после использовать recv()). Но это не работает
Потому что данные приходят не в ListenS, а в CN. Сделай if(WasEvent(CN)) //есть

Добавлено через 3 минуты
Цитата Сообщение от Dimgo2 Посмотреть сообщение
if( FD_ISSET(sock, &read_fds) || result != 0 ) //есть данных
* * * * return true;
* * return false; //нет данных
Здесь, наверное, надо
C++
1
return result > 0 &&  FD_ISSET(sock, &read_fds);
1
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
11.08.2019, 20:43  [ТС]
Да, реально, но эту ошибку( if(WasEvent(CN)) ) я сделал, когда писал эту тему. То есть тестируемый код был исправен(насчет return result > 0 && FD_ISSET(sock, &read_fds); , это я исправил, а if(WasEvent(CN)) уже было). Но это все равно не работает.
Миниатюры
Winsock sellect(), recv()  
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2019, 20:48
Цитата Сообщение от Dimgo2 Посмотреть сообщение
Но это все равно не работает.
int result = select(1, &read_fds, NULL, NULL, &timeout);
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
11.08.2019, 21:01  [ТС]
Вообщем, я думаю, это проблемы у меня с библиотекой/компилятором, т.к. после я попытался просто получить сообщение, нифига. Я думаю, тема закрыта. После исправления ошибки, я надеюсь все будет норм.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2019, 21:03
Цитата Сообщение от Dimgo2 Посмотреть сообщение
, т.к. после я попытался просто получить сообщение, нифига.
select отработал?
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
11.08.2019, 21:25  [ТС]
Нет, я просто поставил так, чтобы через пять повторов WasEvent, WasEvent возвращал true
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
14.08.2019, 07:57
Цитата Сообщение от Dimgo2 Посмотреть сообщение
не могу понять почему
ну, возможно, потому, что данные вообще до вашего сервера не доходят.
Цитата Сообщение от Dimgo2 Посмотреть сообщение
Вообщем, я думаю, это проблемы у меня с библиотекой/компилятором
ну конечно! у всех годами исправно работает, только у вас какая-то ошибка возникает. точно компилятор тупит.

скорее всего, вы просто что-то делаете неправильно либо в сервере, либо в клиенте.
где конкретно - выяснять только вам, т.к. никакого кода вы больше не предоставили.
а то, что предоставили, и то содержало неточности.
1
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
18.08.2019, 11:29  [ТС]
Вообщем, то да, GbaLog- , ты прав. Ошибка была в строке
C++
1
accept(ListenS, (sockaddr*)&adrr, &sizeofAddr);
. Вместо этого должно быть:
C++
1
accept(ListenS, NULL, 0);
,ну или
C++
1
2
3
4
sockaddr_in empty;
int len = sizeof(empty);
ZeroMemory(&empty, len)
accept(ListenS, (sockaddr*)&empty,&len);
.Я же пытался втащить адрес присоединившегося клиента в бинденый адрес. То есть addr- адрес сервера,(адрес ,к которому сервер биндился, то есть был bind(ListenS, (sockaddr*)&adrr, &sizeofAddr) ).
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
19.08.2019, 09:18
Цитата Сообщение от Dimgo2 Посмотреть сообщение
Вообщем, то да, GbaLog- , ты прав. Ошибка была в строке
Это вряд ли. Адрес здесь вообще ни на что не влияет, он чисто для информации.
Кстати, а что у тебя возвращает этот accept, что-то больше нуля?
0
0 / 0 / 0
Регистрация: 11.11.2017
Сообщений: 50
28.08.2019, 15:28  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Это вряд ли. Адрес здесь вообще ни на что не влияет, он чисто для информации.
Кстати, а что у тебя возвращает этот accept, что-то больше нуля?
. Да, функтия возвращает 308. Опять таки, после исправления, все норм заработало.
Цитата Сообщение от Dimgo2 Посмотреть сообщение
Вообщем, то да, GbaLog- , ты прав. Ошибка была в строке
C++Выделить код
1
accept(ListenS, (sockaddr*)&adrr, &sizeofAddr);
. Вместо этого должно быть:
C++Выделить код
1
accept(ListenS, NULL, 0);
,ну или
C++Выделить код
1
2
3
4
sockaddr_in empty;
int len = sizeof(empty);
ZeroMemory(&empty, len)
accept(ListenS, (sockaddr*)&empty,&len);
.Я же пытался втащить адрес присоединившегося клиента в бинденый адрес. То есть addr- адрес сервера,(адрес ,к которому сервер биндился, то есть был bind(ListenS, (sockaddr*)&adrr, &sizeofAddr) ).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.08.2019, 15:28
Помогаю со студенческими работами здесь

recv winsock, или как получить данные
приложение клиент-сервер на winsock допустим клиент законнектился к серверу. Сервер в свою очередь кинул обработку клиента в отдельный...

Winsock. Recv с ошибкой 10053(WSAECONNABORTED)
Приветствую. Сначала отсылаю запрос на сервер, получаю ответ, обрабатываю. Всё хорошо, но вот после отправки второго запроса,...

WinSock - recv возвращает не весь ответ?
Привет всем. Столкнулся с такой проблемой. Работаю с UDP сервером, посылаю ему запрос и на чтение recv или recvfrom, читает...

Вектор и recv
вообщем у меня такая проблема, пытаюсь создать массив с помощью вектора и в него запихнуть то что было принято функцией recv, но выдает...

Функция recv()
Хэлоу! Несколько вопросов по поводу использования функции recv() в Linux: 1) функция не успевает обработать все пришедшие пакеты и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru