Модераторы: marykone
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Управление трафиком, управление отдачей файлов 
:(
    Опции темы
malphunction
  Дата 25.1.2008, 04:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 18.8.2006

Репутация: нет
Всего: нет



У меня есть следующая задача: есть сервер, который отгружает клиентам файлы; есть клиенты, которые получают список файлов и сами файлы. Пользователь видит список и должен управлять файлами: отменять закачку, переставлять файлы. Все это происходит на Win32/64 с использованием TCP.

Проблема в том, что пользователи сидят на модемах, с разными скоростями (от 300 bps и до 36 kbps), а сервер стоит в сети провайдера с широким каналом и не "знает", какой клиент к нему подсоединился. Следовательно, вот такой код:

Код

while(/*все файлы*/)
{
  vector<byte> file = /* прочесть файл */;
  send(sock, &file[0], file.size());
}



приводит к тому, что все файлы оказываются в буфере отправки, и send() возвращает управление почти сразу. Следовательно, никакого управления уже не получиться.

Так вот вопрос -- как сделать так, чтобы возможность контроля оставалась? Т.е. send() отсылал данные со скоростью, с которой клиенты принимают данные. При этом стоит проблема экономии трафика: очень много клиентов сидят на 300 bps с высокой повременной оплатой, хотелось бы, чтобы дополнительных данных было как можно меньше.

Я пробовал setsockopt(socket, SO_BUF, 0), но это не помогает: видимо данные уже не буферезируются на клиенте, но все равно "улетают" сразу, т.к. сервак в локальной сети провайдера находится, и данные там передаются быстро.

Вариант типа "сервер отправляет данные, ждет подтверждения от клиента, снова отправляет данные" не подходит, т.к. канал часто будет простаивать (в ожидании подтверждения). С другой стороны, нечто подобное делает TCP, когда подтверждает получение пакета. Возможно ли как-то получить эти подтверждения, чтобы определить скорость? Но все равно, кажется, это не подходит, т.к. пакеты проходят через маршрутизатор и там могут быть пересобраны, следовательно, на сервер придут подтверждения от маршрутизатора, а не от клиента.

Пока я сделал такую реализацию: клиент отсылает свою максимальную скорость, и сервер отдает данные с этой скоростью. У этого решения вижу несколько минусов: если скорость на модеме падает, то нет соответствующей подстройки, и сервер отправляет данные быстрее, чем клиент их успевает отменить.
PM MAIL   Вверх
ZeeLax
Дата 25.1.2008, 06:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 4388
Регистрация: 20.8.2006
Где: Алма-Ата

Репутация: 19
Всего: 88



Цитата(malphunction @  25.1.2008,  07:43 Найти цитируемый пост)
У меня есть следующая задача: есть сервер, который отгружает клиентам файлы; есть клиенты, которые получают список файлов и сами файлы. Пользователь видит список и должен управлять файлами: отменять закачку, переставлять файлы. Все это происходит на Win32/64 с использованием TCP.

Теперь подробнее, кто за чем сидит и чем управляет.


--------------------
Utility is when you have one telephone, luxury is when you have two, opulence is when you have three — and paradise is when you have none.
— Doug Larson
PM MAIL WWW ICQ Skype Jabber   Вверх
malphunction
Дата 26.1.2008, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 18.8.2006

Репутация: нет
Всего: нет



Сервер стоит тут, у меня под рукой, подключен через выделенку на 256 Kbps. На сервере Win2003.

По миру раскиданы куча пользлователей, которые с помощью спутниковых телефонов выходят в инет (через своих провайдеров) и подключаются к моему серверу. Максимальная достижимая скорость на таком соединении 300 байт в секунду (именно байт в секунду). Соединение неустойчиво, часто рвется. Поэтому средняя эффективная скорость -- где-то 200 байт в с., и скачать можно где-то 1-2 мб, после чего связь почти гарантированно рвется, нужно перезванивать. А, да! Связь очень дорогая, т.е. нужно эту связь максимально полно использовать -- нельзя, чтобы канал простаивал.

Клиент взаимодействует с сервером через TCP, протокол взаимодействия -- собственный.

Задача следующая: На сервере есть файлы, которые нужны пользователям. Обычно пользователю доступно 20-30 файлов размером 50Кб, и 3-4 файла размером 1-3 Мб. Список файлов регулярно пополняется. Не все эти файлы одинаково важны пользователю: одни нужно получить очень срочно, желательно в текущем сеансе связи. Другие не нужны нафиг, их не нужно получать. Третьи хорошо бы получить, но можно и в следующем сеансе связи и т.п. Приоритетность файлов может определить только сам пользователь, у файлов нет каких-л. свойств, по которым их можно было бы предварительно отсортировать на сервере. Т.е. пользователь должен посмотреть описания файлов, упорядочить список и получить нужные файлы в нужном порядке. Пользователь может просматривать описания файлов довольно продолжительное время -- от 1-10 минут (это важно в связи с дороговизной связи) Файлы нужно получать в том же сеансе связи (ну или после дозвона, но это уже другая задача). Но обычно (и это важно) пользователю нужны все файлы.

А, ещё и сам пользователь отправляет свои файлы (хотя тут никто уже ничего не контролирует, просто отправляются все файлы). Просто канал "клиент-сервер" не простаивает, а тоже используется.

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

У этого очевидного решения один минус: сервер отправляет все файлы меньше чем за секунду (они остаются где-то в буферах сервера и т.п. Ну так и должно быть, если почитать описание функции send() -- записать данные в буфер и тут же вернуть управление). Так вот, сервер отправляет данные за секунду, и после этого ничего уже с ними поделать не может. Т.е. если пользователь захочет отказаться от файла, пошлет серверу запрос "удалить файл #1234", сервер примет его, а файл-то уже послан... Хотя клиент сможет получить его только через полчаса.

Подходы, которые я придумал для решения этой проблемы, я описал в первом посте. Проблем у текущего принятого решения две:
1. Эффективная скорость -- 200 байт в секунду, а сервер отсылает со скоростью 300 б/с, поэтому через некоторое время сервером будут отосланы файлы, которые пользователь бы ещё успел проконтролировать.
2. Скоро предвидится апгрейд системы, скорость будет варьироваться от 300 б/с до 36 кб/с, но управляться третьей стороной -- провайдером. Т.е. однозначно установить значение скорости нельзя.

Другое решение, до которого я додумался: клиент регулярно отсылает серверу количество скачанных байт, на основе которых сервер определяет эффективную скорость. Но это уже смахивает на реализацию TCP через TCP. Поэтому вопрос: есть ли в TCP (в реализации WinInet) какие-то средства для определения эффективной скорости клиента (или количества прочитанных им байт)?

Это сообщение отредактировал(а) malphunction - 26.1.2008, 16:02
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Сетевые технологии | Следующая тема »


 




[ Время генерации скрипта: 0.0402 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.