Некоторые вопросы касательно сокетов....
От: Forgotten  
Дата: 26.12.06 10:41
Оценка:
Ситуация классическая.
Клиент — сервер. Клиент подключается и начинает принимать данные. Сервер через некоторый таймаут отправляет данные пока от клиента не получит сигнал о закрытии коннекта. Загвоздка вот в чем. Клиенту нужно переодически выводить данные на экран. И здесь ничего не получается. Функция получения данных с сокета не возвращает управление пока сервер продолжает посылать данные. Технически все реализовано в виде двух бесконечных циклов как на клиенте так и на сервере. Выход из них осуществляется када юзер в клиенте щелкнет на кнопку. Нужно каким-то образом приостановить прием данных, чтоб вывести на экран а потом опять продолжить. И как это сделать кроме как прервать коннект и заново приконнектится — я не знаю. Прошу сильно не ругать если вопрос слишком ламерский. С сокетами познакомился буквально "вчера". Наверняка существует способ сделать все это легко и красиво.
Заранее спасибо.
Re: Некоторые вопросы касательно сокетов....
От: Cruser Украина  
Дата: 26.12.06 11:00
Оценка:
Здравствуйте, Forgotten, Вы писали:

F>Ситуация классическая.

F>Клиент — сервер. Клиент подключается и начинает принимать данные. Сервер через некоторый таймаут отправляет данные пока от клиента не получит сигнал о закрытии коннекта. Загвоздка вот в чем. Клиенту нужно переодически выводить данные на экран. И здесь ничего не получается. Функция получения данных с сокета не возвращает управление пока сервер продолжает посылать данные. Технически все реализовано в виде двух бесконечных циклов как на клиенте так и на сервере. Выход из них осуществляется када юзер в клиенте щелкнет на кнопку. Нужно каким-то образом приостановить прием данных, чтоб вывести на экран а потом опять продолжить. И как это сделать кроме как прервать коннект и заново приконнектится — я не знаю. Прошу сильно не ругать если вопрос слишком ламерский. С сокетами познакомился буквально "вчера". Наверняка существует способ сделать все это легко и красиво.
F>Заранее спасибо.

Непонятно, как обрабатывается щелчок юзером на кнопку, если цикл зависате до конца приёма? Если же он обрабатывается, то тогда и данные можно выводить..

Вообще два основных пути, первый лучше имхо:

1) Принимать в дополнительном потоке (отображать в основном)
2) В цикле приёма, вызывать что-то вроде ProcessMessages() таким образом будут обрабатываться сообщения окна, и можно отображать данные
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Некоторые вопросы касательно сокетов....
От: Garrett Россия  
Дата: 26.12.06 12:17
Оценка:
Здравствуйте, Forgotten, Вы писали:

F>Ситуация классическая.

F>Клиент — сервер. Клиент подключается и начинает принимать данные. Сервер через некоторый таймаут отправляет данные пока от клиента не получит сигнал о закрытии коннекта. Загвоздка вот в чем. Клиенту нужно переодически выводить данные на экран. И здесь ничего не получается. Функция получения данных с сокета не возвращает управление пока сервер продолжает посылать данные. Технически все реализовано в виде двух бесконечных циклов как на клиенте так и на сервере. Выход из них осуществляется када юзер в клиенте щелкнет на кнопку. Нужно каким-то образом приостановить прием данных, чтоб вывести на экран а потом опять продолжить. И как это сделать кроме как прервать коннект и заново приконнектится — я не знаю. Прошу сильно не ругать если вопрос слишком ламерский. С сокетами познакомился буквально "вчера". Наверняка существует способ сделать все это легко и красиво.
F>Заранее спасибо.

Принял кусок данных — показал.
Принял — показал.
Все просто.
в борьбе со здравым смыслом победа будет за нами!
Re[2]: Некоторые вопросы касательно сокетов....
От: Forgotten  
Дата: 26.12.06 21:31
Оценка:
Здравствуйте, Cruser, Вы писали:
C> Непонятно, как обрабатывается щелчок юзером на кнопку, если цикл зависате до конца приёма? Если же он обрабатывается, то тогда и данные можно выводить..

C> Вообще два основных пути, первый лучше имхо:


C> 1) Принимать в дополнительном потоке (отображать в основном)

C> 2) В цикле приёма, вызывать что-то вроде ProcessMessages() таким образом будут обрабатываться сообщения окна, и можно отображать данные

Надо было сразу оговорить что клиент на php. И в этом засада конркретная.
Получается так что пока сервер посылает данные функция приема данных из сокета управления не возвращает? Или все же она получает блок размером, указанным параметром, и завершает работу?
Re: Некоторые вопросы касательно сокетов....
От: Forgotten  
Дата: 05.01.07 21:15
Оценка:
Еще хотелось бы узнать кое-что.
Задача в следующем. Как заставить сервер все время ожидать подключения? То есть допустим клиент подключился, потом отключился а сервер продолжает ждать. Есть совершенно обычный код с последовательными вызовами socket() bind() listen() accept() close(). Вроде все работает. Но когда я все это пытаюсь запустить в цикле, начинаются ошибки. В частности на бинде после завершения одного витка цикла 10048 WSAEADDRINUSE. Видимо происходит от того, что неверно освобождается хендл сокета. Подскажите пожалуйста как вообще правильно это можно реализовать, чтобы сервер продолжал быть работоспособным после разрыва связи с клиентом. Или где про это можно почитать. Заранее спасибо.
Re[2]: Некоторые вопросы касательно сокетов....
От: Аноним  
Дата: 05.01.07 22:36
Оценка:
Здравствуйте, Forgotten, Вы писали:

F>Еще хотелось бы узнать кое-что.

F>Задача в следующем. Как заставить сервер все время ожидать подключения? То есть допустим клиент подключился, потом отключился а сервер продолжает ждать. Есть совершенно обычный код с последовательными вызовами socket() bind() listen() accept() close(). Вроде все работает. Но когда я все это пытаюсь запустить в цикле, начинаются ошибки. В частности на бинде после завершения одного витка цикла 10048 WSAEADDRINUSE. Видимо происходит от того, что неверно освобождается хендл сокета. Подскажите пожалуйста как вообще правильно это можно реализовать, чтобы сервер продолжал быть работоспособным после разрыва связи с клиентом. Или где про это можно почитать. Заранее спасибо.

Это все не нужно запускать в цикле. Последовательность socket() bind() listen() вызываешь один раз при старте сервера, а потом в цикле вызываешь accept(). псевдокод:


SOCKET listener = socket();
bind(listenner);
listen(listener);

for (;;)
{
    SOCKET client = accept(listener);
    if (client != INVALID_SOCKET)
    {
         clients_queue.add(client);
    }
    else
    {
         err = WSAGetLastError();
         break;
    }
}

closesocket(listener);
Re[3]: Некоторые вопросы касательно сокетов....
От: Forgotten  
Дата: 05.01.07 23:30
Оценка:
А>Это все не нужно запускать в цикле. Последовательность socket() bind() listen() вызываешь один раз при старте сервера, а потом в цикле вызываешь accept(). псевдокод:


А>
А>SOCKET listener = socket();
А>bind(listenner);
А>listen(listener);

А>for (;;)
А>{
А>    SOCKET client = accept(listener);
А>    if (client != INVALID_SOCKET)
А>    {
А>         clients_queue.add(client);
А>    }
А>    else
А>    {
А>         err = WSAGetLastError();
А>         break;
А>    }
А>}

А>closesocket(listener);

А>



Я так пытался сделать сначала. Клиент вообще подвисал на неопределенный срок, хотя сервер говорил что он уже получил свои данные.
Вот примерный код. У меня только один поток и все происходит в одном месте.
while(1)
    {
        SOCKET AcceptSocket;
        int bytesSend;
            char* megabuf="data";            
        AcceptSocket=SOCKET_ERROR;
        while(AcceptSocket==SOCKET_ERROR)
            AcceptSocket=accept(mSocket,NULL,NULL);
        mSocket=AcceptSocket;
        bytesSend=send(mSocket,megabuf,strlen(megabuf),0);
        closesocket(AcceptSocket);
    }

Что-то мне не нравится mSocket=AcceptSocket. Это было содрано мной из MSDN. Видимо сам алгоритм работы с сокетами не правильный. По ходу тот сокет, который прослушивает должен только принять коннект и связать его с другим сокетом, который собснно и будет рабочим. Это мысли в слух. Как все работает понятия не имею, но очень бы хотелось узнать. Спасибо за терпение.
Re[4]: Некоторые вопросы касательно сокетов....
От: Аноним  
Дата: 06.01.07 11:01
Оценка:
Здравствуйте, Forgotten, Вы писали:

Сравни свой и мой код, приведенный ранее, неужели они похожи?
Немного переделал твой код, советую хоть что-то почитать о сокетах...
F>
        while(1)
F>    {
F>        int bytesSend = 0;
F>              char* megabuf="data";
            
F>        SOCKET AcceptSocket=accept(mSocket,NULL,NULL);
F>        if (AcceptSocket==SOCKET_ERROR)
                    break;

F>        bytesSend=send(AcceptSocket,megabuf,strlen(megabuf),0);
F>        closesocket(AcceptSocket);
F>    }
F>
Re[5]: Некоторые вопросы касательно сокетов....
От: Forgotten  
Дата: 07.01.07 15:52
Оценка:
Спасибо за помощь.
Вся соль как раз и была в этом неправильном присваивании сокета....
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.