Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.03.2017, 13:32   #1
Ensom ulv
Новичок
Джуниор
 
Регистрация: 02.03.2017
Сообщений: 3
По умолчанию Зависает форма при считывании из сокета

Здравствуйте! Подскажите, в какую сторону двигаться. Суть такая: нажимаю на одну кнопку, происходит подключение к сокету (тут все нормально), нажимаю на другую и начинаю считывать строки. Пока информация считывается приложение-клиент зависает и на другие кнопки не реагирует, к примеру, на кнопку разрыва соединения. Так же строки не отображаются, пока не закончится передача. Почему такое происходит понятно – пока не выйду из бесконечного цикла считывания из сокета, не завершится событие, следовательно все виснит и ничего не сделать. Конечно все отвисает когда передача закончится.

Мне нужно сделать так, чтобы после нажатия на кнопку начиналась передача (это есть), но пока данные передаются я мог спокойно, к примеру, разорвать соединение, если сокет пуст, или подключиться к другому серверу, в общем дальше работать с приложением, а то я даже его закрыть без зависания и ошибки не могу. Так же надо чтобы информация отображалась по мере поступления, а не после завершения события (эта задача второстепенная но тоже важная). Получаемые строки вывожу в listbox.

Надеюсь ясно описал проблему.
Windows form, C++.
Код кнопки, которая пр нажатии посылает серверу сообщение, что можно начинать передачу, в бесконечном цикле считывает строки и выводит их в listbox.

Код:
    private: System::Void button5_Click(System::Object^  sender, System::EventArgs^  e) {
 
        String ^buf;
        char message[10];                       // буфер для принимаемого сообщения
        char start[10] = "START";               // команда серверу для начала передачи
        memset(message, 0, sizeof(message));
 
        if (SOCKET_ERROR == (send(s, start, sizeof(start), 0))) {   // посылаю серверу сообщение, что можно начинать передачу
            error = WSAGetLastError();
        }
        else {
            buf = gcnew String(start);
            listBox1->Items->Add(buf);
            buf = "";
        }
        do {
            if (SOCKET_ERROR == (recv(s, message, sizeof(message), 0))) {
                error = WSAGetLastError();
            }
            else {
                buf = gcnew String(message);                // | вывод принятого сообщения
                listBox1->Items->Add(buf);                  // | в символьном виде
 
                if (strcmp(message, "S T O P !") == 0) {    // Условие для выхода из бесконечного цикла
                    break;
                }
                memset(message, 0, sizeof(message));
                buf = "";
            }
        } while (true);
        delete buf;
    }
Ensom ulv вне форума Ответить с цитированием
Старый 02.03.2017, 13:48   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Есть стандартные 3 пути:
1. Выносить сетевую часть в отдельный поток
2. Использовать асинхронные операции
3. "Имитировать" асинхронность - например, проверять наличие данных селектом c маленьким таймаутом и пока их нет выполнять что-то другое
p51x вне форума Ответить с цитированием
Старый 02.03.2017, 13:58   #3
Ensom ulv
Новичок
Джуниор
 
Регистрация: 02.03.2017
Сообщений: 3
По умолчанию

Можно расписать более подробно?
Пока с этим не сталкивался, может есть какой-нибудь простенький пример, тема или статья? Какими методами пользоваться?
Ensom ulv вне форума Ответить с цитированием
Старый 02.03.2017, 14:04   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Что именно расписать? Вы склоняетесь более в ВинАПИ сторону или в дот нет? Или может вообще буст вас спасет...
p51x вне форума Ответить с цитированием
Старый 02.03.2017, 14:22   #5
Ensom ulv
Новичок
Джуниор
 
Регистрация: 02.03.2017
Сообщений: 3
По умолчанию

Пока мне вообще не ясно в какую сторону шагать, сейчас лучше самый простой способ. Может асинхронные операции?
Ensom ulv вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Зависает форма при закрытии порта Принтер C# (си шарп) 1 24.12.2015 15:15
C# WPF Зависает форма при использовании awesomium (замена webbrowser) Senk WPF, UWP, WinRT, XAML 8 17.10.2013 18:44
Зависает при считывании данных Aleksandr Общие вопросы Delphi 2 04.10.2013 10:30
Форма зависает AcTiV Общие вопросы .NET 2 17.09.2013 17:42
При выполнении кода форма зависает. Как вывести прогрессбар? plato Общие вопросы Delphi 4 06.01.2010 15:37