Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26067
Рейтинг: 2121
#31: 2008-05-14 20:45:19 ЛС | профиль | цитата
tsdima писал(а):
подправить doCaption у WinTools, он ведь тоже из той же оперы (делает SetWindowText), реализовать его через посылку WM_SETTEXT и ограничиться этим

Мне кажется, что не стоит лезть в этот компонент, а сделать свою группу клиент-сервер передачи данных между приложениями на базе запроса WM_SETTEXT с учетом типа данных, вот только какая длина передаваемой строки, в данном случае

Ознакомился с WM_COPYDATA -- там требуется заполнять специальную структуру, еще и с оконным дексриптором источника.

А насчет типов, то можно ограничится четырьмя, тк Stream можно преобразовать во что угодно.
карма: 22

0
Ответов: 2125
Рейтинг: 159
#32: 2008-05-14 21:38:15 ЛС | профиль | цитата
nesco писал(а):
там требуется заполнять специальную структуру, еще и с оконным дексриптором источника

А разве это плохо? А дескриптор источника можно и не указывать, это просто соглашение о назначении wParam, скорее всего.
карма: 1

0
Администрация
Ответов: 15294
Рейтинг: 1518
#33: 2008-05-15 22:40:49 ЛС | профиль | цитата
я бы такую паередачу делал на юлдее предсказуемых в работе маил слотах или еще лучше - пайпах(pipe).
карма: 26
0
Разработчик
Ответов: 26067
Рейтинг: 2121
#34: 2008-05-16 03:59:25 ЛС | профиль | цитата
Ну, не знаю, не знаю... Я порыскал в инэте -- очень неплохой отзыв об WM_COPYDATA. Такая знаменитая программа, как TotalCommander, и то применяет такой способ обмена. А чем, собственно, этот метод не нравится в пределах одного пользователя и одного рабочего стола
На данный момент я добился передачи трех типов данных (уже готовы компоненты клиент/сервер), все передается очень даже быстро и синхронно.
------------ Дoбавленo:

Ну pipe, тоже интересно

От других аналогичных объектов именованные каналы отличает гарантированная доставка сообщений, возможность асинхронного ввода/вывода, возможность коммуникации между процессами на разных компьютерах в локальной вычислительной сети и относительная простота использования.


Вот именно -- относительная простота использования. Стянул пример, не совсем он и маленький.

Ну можно, закончить тот способ обменя и заняться этим.

------------ Дoбавленo:

Майл слоты всем хороши, но передают только текст, в отличии от WM_COPYDATA, который передает любые типы данных.

Можно попробовать создать тестовую программку на предмет вычисления быстродействия передачи Stream'ов через Майл слоты и через HDE (я этот способ обмена так назвал), включая подготовительный этап по начальной и конечной обработки Stream'ов.
------------ Дoбавленo:

Короче, фигня все это. Куча геморроя, и никакого большого толка. Лучше остановиться на майл слотах (почти тоже самое по функционалу) и не изобретать велосипед...
карма: 22

0
Ответов: 2125
Рейтинг: 159
#35: 2008-05-16 13:35:01 ЛС | профиль | цитата
nesco писал(а):
Куча геморроя, и никакого большого толка. Лучше остановиться на майл слотах

О как

карма: 1

0
Разработчик
Ответов: 26067
Рейтинг: 2121
#36: 2008-05-16 20:12:11 ЛС | профиль | цитата
tsdima, есть, конечно, одно различие -- майл слоты работают асинхронно, а WM_COPYDATA -- синхронно, но только в пределах одного рабочего стола, и у него проблема с Vist'ой.
------------ Дoбавленo:

Хотел применить MailSlot для своей проги, так кучу косяков надыбал (как оно раньше работало ). Вместо 10 байт принимало весь буфер скопом (512 байт), причем, добавляло к моей строке еще какую-то дрянь.
tsdima, глянь, я поправил это безобразие на SVN
У себя проверял, сервер и клиент работают точно -- сколько передало, столько и приняло.
карма: 22

0
Ответов: 2125
Рейтинг: 159
#37: 2008-05-16 20:37:39 ЛС | профиль | цитата
Насчёт размера: 512 - ни туда, ни сюда. Если посылать всем компьютерам домена, то должно быть не больше 400 байт, а если в конкретный слот - не больше 64Кб. Так что можешь увеличить размер буфера до 64Кб Либо запрашивать функцией GetMailslotInfo. А ещё, мне не нравится, что SetLength выполняется 100 раз в секунду, можно сделать один раз до цикла, а потом ещё и внутри if после Sender.Synchronize(SyncExec);

карма: 1

0
Разработчик
Ответов: 26067
Рейтинг: 2121
#38: 2008-05-17 14:35:44 ЛС | профиль | цитата
tsdima писал(а):
512 - ни туда, ни сюда

А вот это не я придумал, так и было раньше. Но сейчас поправлю.

А сколько это будет в байтах, мне кажется, что должно быть 65534 плюс 0-й байт и конец строки #0, и тогда получается 65536

------------ Дoбавленo:


tsdima писал(а):
запрашивать функцией GetMailslotInfo

Пожалуй, лучший вариант, но это же только в сервере, в клиенте этого нет, или тоже надо ограничить


------------ Дoбавленo:


Тут фигня получается -- GetMailslotInfo выдает размер столько, сколько прописано в CreateMailslot, если поставить 0 (неограниченный размер), то считывает тоже 0, и чего делать дальше

------------ Дoбавленo:


tsdima писал(а):
потом ещё и внутри if после Sender.Synchronize(SyncExec);

А нафиг не надо в if, только один раз, перед созданием потока, больше он не меняется, специально проверил, но это если как я сделал, с копированием в окончательную переменную, длину которой, устанавливаем по факту чтения.

------------ Дoбавленo:


И не дофига ли резервирование буфера в 64 кб Прикинь, каждый созданный слот будет резервировать 64 кило

------------ Дoбавленo:


Я вот чего накидал, может так лучше будет



function THIMailSlot_Server._OnExec;
var nBytesRead:cardinal;
begin
while not Sender.Terminated do begin
if ReadFile(ms, str[1], MAXWORD, nBytesRead, nil) then begin
SetLength(str,nBytesRead);
s := str;
SetLength(str,MAXWORD);
Sender.Synchronize(SyncExec);
end;
end;
Result := 0;
end;
Тут получается, что в s я копирую уже не 64 кило, а только, сколько приняли, после чего сам буфер str возвращается к исходному размеру и готов в следующем запросе уже принимать данные, а что будет с s уже никого не волнует.

------------ Дoбавленo:


Или все таки, вот так более правильно



function THIMailSlot_Server._OnExec;
var nBytesRead:cardinal;
begin
while not Sender.Terminated do begin
if ReadFile(ms, str[1], MAXWORD, nBytesRead, nil) then begin
SetLength(str,nBytesRead);
Sender.Synchronize(SyncExec);
SetLength(str,MAXWORD);
end;
end;
Result := 0;
end;

Но не получится ли здесь так, что когда я даю комманду на исполнение SyncExec, в SyncExec может произойти задержка в обработке буфера, и наступит время исполнения следующего _OnExec, а буфер-то не определен еще
Я припоминаю, что у себя я такое встречал, когда организовал поток в Com-порту, практически по такой же схеме, но обработчик буфера был очень длинный и тормознутый, в результате, мне пришлось делать промежуточный буфер, как в первом варианте.

------------ Дoбавленo:


Ну что, я добил HDE (HiAsm Date Exchange). Что мне понравилось, так это, практически мгновенная, пересылка очень больших стримов. Картинки размером 1024x768 дольше отрисовывало, чем передавало (теперь понятно, почему Total так шустро вскрывает и передает тексты любой длины).
карма: 22

0
файлы: 1project_hde_1_00.zip [5.9KB] [303]
Администрация
Ответов: 15294
Рейтинг: 1518
#39: 2008-05-17 14:43:38 ЛС | профиль | цитата
nesco, передача через сообщения Windows чревата проблемами при использование Thread. Поэтому хорошее решение это MailSlot или Pipe.

PS: а с упомянутым TC все проще - раньше(до win 2k) ни слотов, ни пайпов не было...
карма: 26
0
Разработчик
Ответов: 26067
Рейтинг: 2121
#40: 2008-05-17 14:57:40 ЛС | профиль | цитата
Dilma писал(а):
хорошее решение это MailSlot

tsdima писАл, что у них ограничение в 64 кило, большой стрим не передашь, бить придется на части. Pipe я еще не юзал, хотелось бы знать ограничение размера на передачу данных.
------------ Дoбавленo:

Dilma писал(а):
чревата проблемами при использование Thread

Но их же не обязательно применять, ведь это уже будет асинхронный обмен данными, а не синхронный.
карма: 22

0
Ответов: 2125
Рейтинг: 159
#41: 2008-05-17 19:14:32 ЛС | профиль | цитата
nesco писал(а):
может так лучше будет

Нет, надо сначала SetLength делать, а уж потом туда считывать.

nesco писал(а):
Pipe я еще не юзал, хотелось бы знать ограничение размера на передачу данных

Нету там вроде ограничений.

Pipe и Mailslot, если провести аналогию с сокетами, это соединения TCP и UDP.

карма: 1

0
Разработчик
Ответов: 26067
Рейтинг: 2121
#42: 2008-05-17 20:57:01 ЛС | профиль | цитата
tsdima писал(а):
Нет, надо сначала SetLength делать, а уж потом туда считывать

Чему SetLength делать str или s

Я в первом примере не показал, что перед созданием Thread я уже сделал первый SetLength(str,MAXWORD);

И все таки я не понял, вот так надо, что ли


procedure THIMailSlot_Server._work_doCreate;
begin
if not Assigned(th) then begin
lol:= ReadString(_Data,_data_Name,_prop_Name);
ms := CreateMailslot(PChar('\\.\mailslot\'+lol),0,MAILSLOT_WAIT_FOREVER,nil);
if ms = INVALID_HANDLE_VALUE then
_hi_OnEvent(_event_onStatus,0)
else begin
_hi_OnEvent(_event_onStatus,1);
SetLength(str, MAXWORD);
SetMailslotInfo(ms,10);
{$ifdef F_P}
th := NewThreadforFPC;
{$else}
th := NewThread;
{$endif}
th.OnExecute := _OnExec;
th.Resume;
end;
end;
end;

function THIMailSlot_Server._OnExec;
var nBytesRead:cardinal;
begin
while not Sender.Terminated do begin
if ReadFile(ms, str[1], MAXWORD, nBytesRead, nil) then begin
SetLength(str,nBytesRead);
SetLength(s,nBytesRead);
s := str;
SetLength(str,MAXWORD);
Sender.Synchronize(SyncExec);
end;
end;
Result := 0;
end;
карма: 22

0
Ответов: 2125
Рейтинг: 159
#43: 2008-05-17 21:28:14 ЛС | профиль | цитата
nesco писал(а):
Чему SetLength делать str или s

А зачем их там вообще две?
Раз уж используется строка s, то её и используй, а str там была локальная, зачем-то.

карма: 1

0
Разработчик
Ответов: 26067
Рейтинг: 2121
#44: 2008-05-17 21:37:22 ЛС | профиль | цитата
Ну понял, значит по второму варианту только вместо str -- s

Вот посмотри -- экспериментальный PIPE, тоже односторонний, но может передавать большие стримы
карма: 22

0
файлы: 1project_pipe_1_00.zip [5.1KB] [312]
Ответов: 2125
Рейтинг: 159
#45: 2008-05-17 21:44:18 ЛС | профиль | цитата
nesco писал(а):
экспериментальный PIPE, тоже односторонний

Пардон, а почему односторонний? В оригинале двунаправленный
Это ж как сокет, только pipe
------------ Дoбавленo:

Вообще-то, pipe это ближе к файлам, может стоит как-то по аналогии с FileStream сделать...
карма: 1

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)