![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: 1 Всего: 12 |
Всем привет.
Пишу сервер на НИО. Хочу на каждий запрос создавать новый Thread, 4то бы не ставить клиентов в очередь. Так вот, почемуто создаётся эхо соединения. Тоесть если клиент выслал 1 строчку то сервер по4емуто вызовет READ около 10(может варьироваться) раз. Причём 9 Тредов будер с буффером 0 ,а вот последний раз нормально прочитает буффер будет равен количеству висланых байт. Если убрать из new ServerCommands(sc,keys,key).start(); метод start() то всё работает нормально. Вот код сервера.
|
|||
|
||||
| KOp4iK |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 118 Регистрация: 26.11.2004 Где: Латвия Репутация: нет Всего: 3 |
на сколько я могу предположить
true до тех пор пока ты из него не прочитаешь все пришедшие в него данные... Вот и получается что до тех пор пока ты прочитал все данные ты успеваешь создать 9-10 тредов... Решение как мне кажется: читать в одном треде и только потом передавать данные в тред на выполнение... |
|||
|
||||
| Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: 1 Всего: 12 |
Ведь в коде есть it.remove(); . Поэтому повторной итэрации быть не может. Распиши поподробней пожалуйста.
Это сообщение отредактировал(а) Tony - 27.11.2006, 21:05 |
|||
|
||||
| Tony |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1159 Регистрация: 3.3.2006 Где: Riga Репутация: 1 Всего: 12 |
|
|||
|
||||
| iLoveJava |
|
||||||||
|
Новичок Профиль Группа: Участник Сообщений: 49 Регистрация: 29.7.2007 Репутация: нет Всего: нет |
У меня тоже вопрос по этой теме.
Какая вообще должна быть структура сервера?
Тоесть 1 главный поток который просыпается только при возникновении соответствующих событий и в нем происходит обработка сообщений иначе будет как говорил, KOp4iK
а если много клиентов? мне кажется один поток просто не успеет... У меня сейчас что то типа
Тоесть 1 главный поток который просыпается только при новом подключении, и добавляет его в selector 1 из N потоков, которые уже ждут пока в канале не появятся данные, а потом считывают их и выполняют обработку, по моему и то лучше... НО КАК СДЕЛАТЬ ПРАВЕЛЬНО?!!! И еще один вопрос... Мне требуется не только читать данные но и писать по тому же запросу? как это сделать? у меня сейчас так
|
||||||||
|
|||||||||
| iLoveJava |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 49 Регистрация: 29.7.2007 Репутация: нет Всего: нет |
Насклько я понял читая топик
Nio, select, длиные запросы, сохранение канала, Как реализовать оптимально? структура сервера должна быть такой(я там тоже это написал может хоть кто-то ответит) должен быть цикл с select в, котором для каналов будут считываться и записываться данные, при чем у каждого канала должен быть буфер на чтение и на запись, в этом цикле буфер на чтение будет заполняться, а потом когда накопится все сообщение, то в каком-то рабочем потоке(их наверно должен быть пул) этот буфер обрабатывается и заполняется буфер на запись, который в основном цикле записуется. так чтоли? |
|||
|
||||
| COVD |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
В сети много примеров нио сервера. Мне понравился http://rox-xmlrpc.sourceforge.net/niotut/index.html .
да
Наверное, так, если синхронный обмен данными. В этом случае сервер отвечает на запрос клиента и пока запрос полностью не пришел, то и ответ не отсылается. В асинхронной же схеме клиент может прислать подряд несколько запросов. А сервер будет отвечать по мере готовности ответов, причем ответы могут идти в другом порядке (потому что запросы могут быть разными по тяжести - на одни ответ быстро формируется, на другой медленно). Кроме того, в асинхронной схеме сервер может что-то послать клиенту без запроса, т.е. сделать ему push. Поэтому в асинхронной схеме поток, обслуживающий select , всегда выполняет две операции - чтение и запись: 1. если канал готов к чтению (клиент что-то прислал, хотя бы один байт) , то читает из канала доступные байты в клиентский буфер на чтение. 2. если канал готов к записи и клиентский буфер на запись не пустой (т.е. рабочие потоки, обрабатывающие клиентские запросы, приготовили ответы), то пишет в канал из буфера на запись. Это сообщение отредактировал(а) COVD - 30.7.2007, 15:17 |
||||
|
|||||
| iLoveJava |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 49 Регистрация: 29.7.2007 Репутация: нет Всего: нет |
А разве в такой схеме так не выходит?
1) Приходит 1 запрос, он считывается в основном цикле, потом отдается на выполнение 1 с рабочих потоков, которому на это требуется 5минут; 2) В это время приходит 2 запрос, он считывается в основном цикле, потом отдается на выполнение 2 с рабочих потоков, которому на это требуется 2минут; 3) 2 поток завершает обработку запроса и пишет результат в буфер для отправки данных, с которого потом в основном цикле будут писаться данные в канал; 4) 1 поток завершает обработку запроса и пишет результат в буфер для отправки данных, с которого потом в основном цикле будут писаться данные в канал; параллельно всему этому в основном потоке проверяется есть ли данные на запись если есть то они пишутся. В результате ответ на запрос 2 приходит раньше чем на запрос 1 У меня тут еще один вопрос появился Если я регистрирую канал на чтение и запись, то выходит, что select будет завершаться очень быстро так как канал, практически всегда будет готов на запись, то есть если сервер пишет в канал только результаты запросов, то пока запрос не пришел нет смысла проверять канал на запись в этом есть смысл только если уже пришел запрос(если конечно сервер сам может что-то записать в любой момент клиенту то тогда смысл есть, но все же если эта операция делается очень редко, а даже если часто всеравно не рационально), то есть выйдет что у меня все время будет перебор каналов на запись, а мне туда и писать нечего, как это обойти? Можно канал зарегистрировать сначала на чтение, а когда отправлять на обработку ответа зарегистрировать на запись или после обработки зарегистрировать на запись, а после отсылки всех данных зарегистрировать на чтение(а в таком случае не может быть проблем с асинхронной схемой?)? |
|||
|
||||
| COVD |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Да, вы правильно описали асинхронную модель. А реализуется ли это в вашем коде - не знаю.
Совершенно верно. Про это как раз и написано в ссылке, которую я дал выше.
т.е. это типичная ошибка, которая приводит к тому, что процесс, обслуживаюший селектор, крутится вхолостую и захватывает 99% процессорного времени. Чтобы этого избежать, надо устанавливать опцию OP_WRITE только тогда, когда есть данные на запись. Посмотрите код в ссылке. Там достаточно подробно все обьясняется. |
||||||
|
|||||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Работа с сетью | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |