Russian Qt Forum

Qt => Работа с сетью => Тема начата: virtual_root от Июль 01, 2013, 13:53



Название: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 01, 2013, 13:53
Добрый день. У меня такой вопрос стал. Можно ли из одного сокета параллельно читать данные и писать в него?
Мне конечно кажется что этого нельзя делать. Я поняла что сам сокет это файл в который ведется запись и из которого производится чтение. И во время выполнения этих операций доступ к этому файлу блокируется. Поправьте меня, пожалуйста, если я не правильно поняла. Я написала простенький сервер и клиента. На мой сервер может подключаться по нескольку клиентов и общаться между собой. Пока что само общение клиентов не реализовано, но реализовано общение с сервером. Передо мной стал вопрос что делать в следующей ситуации:
Клиент А хочет передать клиенту B файл. Сервер постепенно выполняет чтение присылаемых данных файла от клиента A. Но в это время другий 2 клиента D и C шлют простый сообщение клиенту A.
Как мне одновременно читать из сокета данные и передать сообщения на этот же сокет.
Соединение с клиентом я устанавливаю так:
Код:
int ns;   // идентификатор соединившегося сокета

/*Принимаем входящий запрос*/
if ((ns = accept(s, (struct sockaddr *)&clnt_addr,&addrlen)) == -1)
{
std::perror("Ошибка вызова accept()\n");
std::exit (-1);
}
else
std::printf ("%s","\nЗапрос на connet принят. Обработка...\n");

Полученный идентификатор сокеты при успешном соединении я добавляю в массив и в другом потоке опрашиваю массив сокетов с помощью функции select на наличие данных для чтения. При поступлении этих данных я планирую выбирать из пула потоков свободный поток и считытвать данные из сокета уже в другом потоке.
Хотела сделать так: свободный из пула потоков не только считывает данные из переданного ему сокета, но и пересылает их другому клиенту.
Но сейчас задумалась над тем, а что если сокета того клиента которому нужно послать сообщение сейчас занят?
И занят надолго? Например получение файла происходит. Как мне тогда передать сообщение?


Может кто знает как это реализовано в скайп? Ведь там во время передачи файла возможно и общение со многими контактами.
Помогите, пожалуйста мне разобраться в этом.
Пишу под Linux.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Bepec от Июль 01, 2013, 13:57
Открою тайну по секрету - один порт для сообщений. Второй порт для сервисных пакетов. Третий порт для передачи файлов. Четвертый ... Ну тут придумать надо :P

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


Название: Re: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 01, 2013, 15:08
Спасибо за открытие тайны))


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 01, 2013, 15:09
Но сейчас задумалась над тем, а что если сокета того клиента которому нужно послать сообщение сейчас занят?
И занят надолго? Например получение файла происходит. Как мне тогда передать сообщение?
А вы шлите большой файл транками (небольшими кусками). А между ними спокойно можно передавать сервисные сообщения и т.д.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 01, 2013, 15:28
У меня ещё поясняющий вопросик. А может один клиент с сервером соединиться несколько раз, чтобы можно было по разным портам передавать разные сообщения ? Как вы и писали Верес. Мне получается нужно сделать несколько коннектов, получить на каждый по сокету и работать с ними?
Извините за глупый вопрос.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 01, 2013, 15:30
У меня ещё поясняющий вопросик. А может один клиент с сервером соединиться несколько раз, чтобы можно было по разным портам передавать разные сообщения ? Как вы и писали Верес. Мне получается нужно сделать несколько коннектов, получить на каждый по сокету и работать с ними?
Извините за глупый вопрос.
Может. Так работает ftp.
Но для чего, если все можно слать по одной трубе?


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Bepec от Июль 01, 2013, 15:33
Очень просто - труба не растягивается. А вот трафик по ней может расти.

К тому же можно совместить идеи - передавать транками (чанками ^.^) по нескольким портам. Получится торрент практически :P

Может клиент соединиться по нескольким сокетам. Может соединяться в случае необходимости. Или же всегда держать соединение - как вам будет угодно.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 01, 2013, 15:39
спасибо за ответы. Буду пробовать.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 01, 2013, 18:41
Очень просто - труба не растягивается. А вот трафик по ней может расти.
А порты ресурс конечный и очень не большой. Для серьезных применений на много пользователей такой подход не подойдет.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Bepec от Июль 01, 2013, 19:30
4 - 5 сокетов на сервер :) Ну и VIP места для передачи афигенных файлов.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 01, 2013, 19:45
4 - 5 сокетов на сервер :)
Почему на сервер? На каждого клиента.
Не считая управления всем этим хозяйством.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Bepec от Июль 01, 2013, 20:17
Э? На клиент? Оо... Неожиданный подход :D


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 01, 2013, 20:34
Э? На клиент? Оо... Неожиданный подход :D
Поэтому я и удивился, что вы его предложили.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 02, 2013, 16:23
а какой тогда подход лучше для многопользовательского сервера? Как пишут сервера у которых по 10 000 соединений?
Я понимаю, что это скорее всего не один сервер, а несколько и между ними распределяются клиенты. Ну интересна как происходит обслуживание клиентских запросов?


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 02, 2013, 18:08
а какой тогда подход лучше для многопользовательского сервера? Как пишут сервера у которых по 10 000 соединений?
Бережно относясь к имеющимся ресурсам. :)
А так, такие темы уже поднимались на форуме не раз.

Я понимаю, что это скорее всего не один сервер, а несколько и между ними распределяются клиенты. Ну интересна как происходит обслуживание клиентских запросов?
10K сможет и один обслужить. Все зависит от того, что же ему нужно будет делать.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: virtual_root от Июль 02, 2013, 22:05
Можете мне ещё подсказать пожалуйста. Когда на мой сервер конектится допутим 10 клиентов одновременно, как лучше их авторизовывать? В одном потоке по очереди или создать несколько потоков?
Я не пойму как сделать так, чтобы подсоеденившегося клиента проверять на подлинность, но при этом другие тоже могли подсоедениться... Мне ведь нужно от клиента который подсоединяется получить специальное сообщение, если я его не получаю, то закрываю соединение. Но как мне зависнуть в ожидании этого сообщения от клиента? Я сейчас делаю просто функцией select с интервалом 1 секунда, если сообщение не пришло то закрываю соединение. Но мне кажется это какой-то неправильный подход..
Подскажите мне пожалуйста.


Название: Re: Паралельная запись и чтение из сокета
Отправлено: Old от Июль 02, 2013, 22:19
Я сейчас делаю просто функцией select с интервалом 1 секунда, если сообщение не пришло то закрываю соединение. Но мне кажется это какой-то неправильный подход..
Что-то я не пойму, вы как приходящие данные читаете, в слоте присоединенном к сигналу readyRead? Или как?
Где вы select используете? Он уже в ядре Qt выполняется и через специальный механизм QSocketNotifier используется.