Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi: Сети
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
1

возможна ли ошибка при таком подходе?

11.06.2013, 21:21. Просмотров 679. Ответов 14
Метки нет (Все метки)

есть приложение оформленое как служба, серверный сокет как stThreadBlocking.
возможна ли ситуация при которой
на строке ServerSocket1.Socket.Connections[i].SendText(msg+'#') приложение зависнет?
заранее благодарен за ответы.

вот непосредсвенно сам код отправки сообщения
Delphi
1
2
for I := 0 to ServerSocket1.Socket.ActiveThreads - 1 do
                 ServerSocket1.Socket.Connections[i].SendText(msg+'#')
Добавлено через 5 часов 37 минут
хм... никто не писал такой код?
буду признателен за любые комментарии и предположения.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.06.2013, 21:21
Ответы с готовыми решениями:

Отладка в стиле быстрых выводов данных и скорость компиляции в таком подходе
Работаю на php, там интуитивно вырабатывается такой подход отладки в стиле -...

Ошибка при установке: Установка Windows в данную область жесткого диска не возможна
Помогите пожалуйста. Не могу установить виндовс на компьютер на каждом разделе...

Можно ли сделать ЧПУ URL при процедурном подходе?
Можно ли при процедурном подходе к построению движка сделать ЧПУ url? Сделал...

Загрузка изображений в ASP.Net MVC при подходе EF Code First
Подскажите или покажите пример загрузки и отображения изображений в ASP.Net MVC...

Вычислить ускорение поезда, если при подходе к станции поезд уменьшил скорость от 90 до 45 км/ч в течении 25 с
3. Составьте программу вычисления ускорения поезда, если при подходе к станции...

14
Dr_Quake
Заблокирован
11.06.2013, 22:15 2
А с чего вдруг? Просто будет очень долго выполняться, пока будут вылетать exceptions таймаута того или иного соединения если оно висит.
0
mss
2634 / 2258 / 276
Регистрация: 24.12.2010
Сообщений: 13,725
11.06.2013, 22:17 3
Конечно возможна.
При вызове SendText возникло исключение, а ты его грамотно не обработал - после этого может быть все что угодно, от "зависания" до краха процесса.

Кроме того, каждый TServerClietThread-объект должен работать со своим сокетом и не лезть в другие коннекты, равно как и основному потоку сервис-процесса тоже нечего совать нос в дела потоков, обслуживающих каждый свое клиентские соединения.
0
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
11.06.2013, 22:56  [ТС] 4
Цитата Сообщение от Dr_Quake Посмотреть сообщение
А с чего вдруг? Просто будет очень долго выполняться, пока будут вылетать exceptions таймаута того или иного соединения если оно висит.
да я бы тоже грешил на таймаут, но зависание длится от нескольких минут до нескольких часов что на таймаут совсем не похоже, или я не прав?
0
Dr_Quake
Заблокирован
11.06.2013, 23:03 5
А это, Петька, ньюансы... На деле я чуть ступил - у тебя же ServerSocket , а это старый доindy компонент, там если руками везде делать synchronized не будет проблем только. И то - в этот момент активные соединения должны не передавать-принимать, а это не только synchronized, это фактически влезание в поток данных соединения на канальном уровне, для этого тебе надо ВСЕ соединения приостановить на передачу, synchronized мало, надо ещё ручками обрабатывать флаг "я сейчас пишу извне" в потоке обработчика соединения.

Вообще - именно лок у тебя лечится трейсом простым, там будет очевидно где проблема, но вот решение её... Используй лучше что-то более высокоуровневое, а лучше делай культурно - вводя флаг такой же, но по которому каждый поток проверяя его приостановитя и пошлёт твой msg+'#', это правильнее с точки зрения кода - потоки не лезут друг к другу.
0
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
11.06.2013, 23:03  [ТС] 6
Цитата Сообщение от mss Посмотреть сообщение
Конечно возможна.
При вызове SendText возникло исключение, а ты его грамотно не обработал - после этого может быть все что угодно, от "зависания" до краха процесса.
спасиба за внимательность... как правильно это сделать
Delphi
1
2
3
4
5
try
for I := 0 to ServerSocket1.Socket.ActiveThreads - 1 do
                 ServerSocket1.Socket.Connections[i].SendText(msg+'#')
except
end;
или достаточно
Delphi
1
2
3
4
5
for I := 0 to ServerSocket1.Socket.ActiveThreads - 1 do
try
 ServerSocket1.Socket.Connections[i].SendText(msg+'#')
except
end;
Цитата Сообщение от mss Посмотреть сообщение
Кроме того, каждый TServerClietThread-объект должен работать со своим сокетом и не лезть в другие коннекты,
.....
где вы это увидели в моих 2 строчках кода, можна подробнее
Цитата Сообщение от mss Посмотреть сообщение
......
равно как и основному потоку сервис-процесса тоже нечего совать нос в дела потоков, обслуживающих каждый свое клиентские соединения.
буду благодарен за совет "как вызвать из основного потока отправку сообщения по сокету для клиента"
0
Dr_Quake
Заблокирован
11.06.2013, 23:09 7
kon123,

P.S. А у тебя случаем таймаут не -1/0 стоит на соединение/read/write итд?

Добавлено через 49 секунд
mss, С правильной синхронизацией все они равны и могут лезть куда угодно, но с оговоркой выше про целостность данных передаваемых внутри TCP сессии, тут синхронизация ПОТОКОВ никак не поможет - необходимо, но не достаточно.
0
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
11.06.2013, 23:22  [ТС] 8
Цитата Сообщение от Dr_Quake Посмотреть сообщение
А это, Петька, ньюансы... На деле я чуть ступил - у тебя же ServerSocket , а это старый доindy компонент, там если руками везде делать synchronized не будет проблем только. И то - в этот момент активные соединения должны не передавать-принимать, а это не только synchronized, это фактически влезание в поток данных соединения на канальном уровне, для этого тебе надо ВСЕ соединения приостановить на передачу, synchronized мало, надо ещё ручками обрабатывать флаг "я сейчас пишу извне" в потоке обработчика соединения.

Вообще - именно лок у тебя лечится трейсом простым, там будет очевидно где проблема, но вот решение её... Используй лучше что-то более высокоуровневое, а лучше делай культурно - вводя флаг такой же, но по которому каждый поток проверяя его приостановитя и пошлёт твой msg+'#', это правильнее с точки зрения кода - потоки не лезут друг к другу.
прошу прощения но мы наверное друг друга не поняли, у меня есть основной поток сервиса, и множество потоков клиентов(создаёться при коннекте и уничтожаеться при отключении клиента)
основной поток передаёт сообщение на открытый сокет клиента, при этом допускаю что возможно уничтожение потока(сокет клиент) подключеного клиента в любой момент, при этом эта конструкции
Delphi
1
2
for I := 0 to ServerSocket1.Socket.ActiveThreads - 1 do
                 ServerSocket1.Socket.Connections[i].SendText(msg+'#')
должна гарантировать что я отправлю запрос именно по назначению, и если что-то произошло в этот момент с ActiveThreads программа должна выпасть в ексепшин

не совсем понял зачем здесь synchronized или какойто флаг?
0
Dr_Quake
Заблокирован
11.06.2013, 23:27 9
ОК, откинем синхронизацию потоков. Допустим в этот момент клиент что-то запросил или сервер что-то послал клиенту, а ты врываясь пишешь в этот сокет свой msg. Так делать нельзя в любом раскладе, придумывай переменные флаги указания потокам соединений что надо что-то передать и уже в потоке хендлера соединения это т флаг обрабатывай и думай куда и когда запихнуть чтобы не нарушить целостность данных.
0
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
11.06.2013, 23:41  [ТС] 10
Цитата Сообщение от Dr_Quake Посмотреть сообщение
kon123,

P.S. А у тебя случаем таймаут не -1/0 стоит на соединение/read/write итд?
созданый поток проверяет наличие коннекта клиента и если в течении 30 секунд от клиента нет ответа поток уничтожаеться после закрытия коннекта к клиенту, о ка ком тайм ауте вы говорите?

Добавлено через 7 минут
Цитата Сообщение от Dr_Quake Посмотреть сообщение
ОК, откинем синхронизацию потоков. Допустим в этот момент клиент что-то запросил или сервер что-то послал клиенту, а ты врываясь пишешь в этот сокет свой msg. Так делать нельзя в любом раскладе, придумывай переменные флаги указания потокам соединений что надо что-то передать и уже в потоке хендлера соединения это т флаг обрабатывай и думай куда и когда запихнуть чтобы не нарушить целостность данных.
не совсем верно,на сколько я разобрался при sendText все данные записываются в буфер последовательно и в таком же порядке будут приняты или переданы на сокет клиента, та же ситуация происходит и с сервером. если я не прав ткните меня носом в документацию.
0
Dr_Quake
Заблокирован
11.06.2013, 23:48 11
kon123, от твоего вызова да, а кто сказал что твой вызов будет эксклюзивен и между send(msg) в цикле ничто не вклинится - в твоём коде все потоки соединений будут в это время исполняться параллельно и никто не гарантирует что они в этот момент не будут ничего передавать.
0
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
12.06.2013, 00:11  [ТС] 12
Цитата Сообщение от Dr_Quake Посмотреть сообщение
kon123, от твоего вызова да, а кто сказал что твой вызов будет эксклюзивен и между send(msg) в цикле ничто не вклинится - в твоём коде все потоки соединений будут в это время исполняться параллельно и никто не гарантирует что они в этот момент не будут ничего передавать.
т.е. если несколько потоков одновременно будут передавать сообщение то у меня возникнет зависание которое не вывалиться в ексепшин?(обязательно проверю но предполагаю что быстрее вывалится ошибка переполнения буфера) тогда вопрос "как правильно это сделать" есть пример кода?(как сделать правильно синхронизацию основного потока с отправкой сообщения на сокет клиента чтобы основной поток не завис, сейчас при зависании основного потока серверсокет отвечает и позволяет клиентам подключаться и отключаться)

также предположим что код написан без ошибок, тогда что может блокировать основной поток при такой конструкции и как этого избежать?
0
Dr_Quake
Заблокирован
12.06.2013, 00:30 13
Я же сказал - через промежуточную глобальную переменную с synchronized обращением к ней из потоков клиентов, видишь что она не ноль или не пустая - завершаешь текущие IO операции и шлёшь содержимое. Смысл - потоки сами должны дёргать переменную, а не произвольный поток дёргать все остальные потоки, никогда не менялся.
0
mss
2634 / 2258 / 276
Регистрация: 24.12.2010
Сообщений: 13,725
12.06.2013, 10:47 14
Цитата Сообщение от kon123 Посмотреть сообщение
как вызвать из основного потока отправку сообщения по сокету для клиента
Потоку А (не важно какому - основному или дополнительному) следует подать тем или иным образом доп.потоку В команду "пошли своему клиенту такое-то сообщение".

По сути это и есть элемент синхронизации межпоточного взаимодействия.
Послать сообщение потоку можно кучей разных способов, начиная от SendMessage/PostThreadMessage и заканчивая QueueUserAPC. Тут нет предела для фантазии, важно только чтобы выбранный метод взаимодействия был оправдан с разных точек зрения.
1
kon123
0 / 0 / 0
Регистрация: 11.06.2013
Сообщений: 7
12.06.2013, 17:20  [ТС] 15
всем спасиба
0
12.06.2013, 17:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2013, 17:20

найти К, при таком-то условиию, беда
помогите плс с работой, препод говорит что нужно как бы не кардинально, но...

Возможна ли ошибка в условии?
Возможна ли ошибка в условии(прилагаю)? :wall: Так как никак не могу понять,...

Возможна ошибка в записи уравнения
дано уравнение моя запись:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru