Как да получите съобщение от TCPServera
Проблемът е, че изпращам съобщение до сървъра procedure TForm1.BitBtn1Click(Sender: TObject); begin IdTCPClient1.WriteLn(‘M"+Memo2.Text); end; на манипулатора на сървъра if Msg[1]="M" then begin BroadcastMessage("E", "New Message"); End; Как клиентът да получи това съобщение, да направи ReadLn на таймера?
procedure TForm1.BitBtn1Click(Sender: TObject); var Response : string; begin IdTCPClient1.WriteLn('M"+Memo2.Text); Response:=IdTCPClient1.ReadLn; end;
и ако има 2 клиента, тогава вторият получава съобщението само като изпрати заявка до сървъра. Как мога да го накарам да приема автоматично? т.е. едно изпратено, отразено ли е върху всички останали клиенти?
Клиентът изпраща съобщение досървъра, а не до други клиенти. За да могат другите клиенти да видят съобщението,сървъръттрябва да изпрати това съобщение до тези клиенти
Да, поне 2 милиона!
> вторият получава съобщението само чрез изпращане на заявка до сървъра
дали е във връзка с [1]? няма нужда да тълкувате ПРИМЕРА толкова буквално.
Как може да се изпрати съобщение от сървъра до клиента? Никъде не намирам такива примери.
> Някак си никъде не намирам такива примери
добре, разбира се. и напишете в помощта за Indie компоненти, например ключовата дума "WriteLn" и вижте кои Indie класове имат този метод - това не е кралска работа ..
Честно погледнах, но ако клиентът изпрати съобщение WriteLn до сървъра, тогава клиентът ще го получи само чрез запитване до сървъра, нали?
Ако отговарящият отговори на въпроса на питащия, тогава питащият ще знае отговора само след като чуе отговора. И така? Или може би по друг начин?
няма друг въпрос как да се реализира излъчвано съобщение, тоест например един клиент изпрати съобщение до сървъра и за товавсички клиенти, свързани към сървъра, трябва да знаят наведнъж. Направете го на таймер, за да анкетирате целия сървър, или да поставите TCP клиент и TCP сървър на едно приложение?
Приложих това на таймер, т.е. след изпращане на съобщение до сървъра (IdTCPServer), моят клиент чака 1,5 секунди (както една млада дама каза: „Шауб със сигурност“) и след това получава информация от сървъра. Относно сървъра. Има събитие OnExecute(AThread: TIdPeerThread), където AThread недвусмислено ИДЕНТИФИЦИРА източника на информация (IdTCPClient, накратко). Следователно, затваряте кода, от който се нуждаете, за това събитие и продължете. Четене (четене от клиент), така че успех.
Какво общо има таймерът? За какво служи?
И вече ви беше казано какво трябва да се направи, така че всички клиенти да получат съобщението на първия клиент.
обектът TIdTCPServer има свойството Threads: TThreadList, това е списък с обекти от класа TIdPeerThread, всеки от които е свързан с активен клиент
обектът TIdPeerThread има свойството Connection: TIdTCPServerConnection
обектът Connection има метод WriteLn().
Добре, значи този код ще изпраща съобщения до всички свързани в момента клиенти? procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var Msg : string; Брой: Цяло число; започнете Съобщение := AThread.Connection.ReadLn; for Count := 0 to IdTCPServer1.Threads.LockList.Count -1 do TIdPeerThread(IdTCPServer1.Threads.LockList.Items[Count]).Connection.WriteLn(Msg); IdTCPServer1.Threads.UnlockList;
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var i: Integer; Съобщение: низ; начало Съобщение:= AThread.Connection.ReadLn; с AThread.Connection.Server.Threads.LockList направете опитайте за i := 0 до Count -1 направете опитайте TIdPeerThread(Items[i]).Connection.WriteLn(Msg); с изключение на край; накрая IdTCPServer1.Threads.UnLockList; край; край;
след това стартира два клиента, единият написа съобщение и натисна бутона procedure TForm1.BitBtn1Click(Sender: TObject); var Response : string; begin IdTCPClient1.WriteLn(Memo2.Text); Response:=IdTCPClient1.ReadLn; end; получи незабавен отговор, вторият седи, без да получава нищо. Или получено, да, не можах да обработя получаването?
> получи незабавен отговор
правилно, получих .. защото IdTCPClient1.ReadLn е изпълнен
и този (друг) клиент, който в този момент "бие палци" без да извика IdTCPClient1.ReadLn, разбира се, не получи нищо.. а какъв страх трябваше да получи нещо. Дори да не си мръдна пръста? zakonnektilsya и седи в очакване на времето край морето?
"който пита, ще получи отговор" (c)
Кога и в кой момент вторият клиент трябва да извика IdTCPClient1.ReadLn, да анкетира сървъра на интервали?
> Кога и в кой момент вторият клиент трябва да извика IdTCPClient1.ReadLn
в момента този клиент иска да получи потенциално изпратено от сървъра низово съобщение
> анкета на сървъра на интервали?
защо иначе е това очаквате ли нещо да получите от сървъра? добре, извикайте ReadLn()! Веднага след като сървърът успее да ви изпрати нещо, функцията ще върне контрола и ще върне получения низ, получен от сървъра
В примерите на DELPHI има програма NETCHAT, както клиентският компонент, така и сървърният компонент лежат във формуляра
> Антон.(6/10/04 11:47 AM) [19] > В примерите на DELPHI има програма NETCHAT точно там във формуляра > лежи както клиентският компонент, така и сървърният компонент
И какво?> Антон. (06/10/04 11:38 AM) [17] > Кога и в кой момент вторият клиент трябва да извика IdTCPClient1.ReadLn, > анкета на сървъра на интервали?
Не анкетирайте сървъра! И вашият собствен сокет, свързан със сървъра Поне на интервали, поне в отделна тема, поне веднага четете и хвърляйте антифриз във формата. Това е въпрос на вкус и пригодност за задачата. Но IdTCPClient няма способността асинхронно, независимо да докладва, че някои получени данни са се появили в неговия сокет.
нещо подобно се случи, вашите оценки?
procedure TForm1.FormCreate(Sender: TObject); var MyThread: TThread; begin IdTCPClient1.Connect; T1 := TMyThread1.Create(False); T1.Priority := tpLowest; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin IdTCPClient1.Disconnect; end;
процедура TForm1.BitBtn2Click(Подател: TObject); начало затваряне; край;
procedure TForm1.ListenServer; begin Memo1.Text:=IdTCPClient1.ReadLn; end;
procedure TForm1.BitBtn1Click(Sender: TObject); begin IdTCPClient1.WriteLn("M"+Memo2.Text); Бележка2.Изчистване; ListenServer; край;
процедура TMyThread1.Execute; започнете докато не е Прекратено do Синхронизиране (DoWork); край;
процедура TMyThread1.DoWork; начало Form1.ListenServer; край;
за абсолютно безсмислено изтръгване на кода на метода TMyThread1.Execute;
> [21] Антон. (06/10/04 17:56) > нещо подобно се оказа, вашите оценки? > > процедура TForm1.FormCreate(Подател: TObject); > var >MyThread: TThread; > начало > Memo2.Clear; > IdTCPClient1.Connect; > T1 := TMyThread1.Create(False); > край; > > процедура TForm1.FormClose(Подател: TObject; var Action: > TCloseAction); > начало > IdTCPClient1.Disconnect; > край; > > процедура TForm1.BitBtn2Click(Подател: TObject); > начало > затвори; > край; >
> процедура TForm1.BitBtn1Click(Подател: TObject); > начало > IdTCPClient1.WriteLn("M"+Memo1.Text); > край; > > процедура TMyThread1.Execute; > начало > докато не е прекратено, направете започнете NewS := IdTCPClient1.ReadLn; ако NewS <> "" след това Синхронизиране(Show_NewS); край; > край; > > процедура TMyThread1.Show_NewS; > begin Memo1.Lines.Add(NewS); > край;
Новини: низ; - поле TMyThread1
P.S. А къде народът бере този шаблон. Изпълнение: докато не е прекратено, направете синхронизиране (DoWork) ? P.P.S. Тази "риба" лошо пахне.
Спасибо грешки понял, учту
некто Карих Николай в свое време подсуетился неудачно . хотя . обвиняват го във всички смъртни грехове също вроде би няма повода - там всъщност в статията като раз думата "шаблон" явно фигурира .
Може да не гоня, но клиентът на това и клиентът да се справя. ИМХО сървърът не може произволно да изпрати клиентска дата. Просто клиентът не иска порт, само по време на изчакване, очаква отговор на сървъра. Може да се слуша и портът да се свърже и да се лови, но това помага вече да бъде сървър, а не клиент.
колка (12.06.04 23:44) [26]
сървърът може да изпрати съобщение на клиент, например при постъпване на съобщение от друг клиент. Това съобщение попада в точката на предназначение и сиди в TCP стеке и жде, когато тамошният клент го опроверга, изпълниReadLn например. Когато TIdTcpClient прави ReadLn, той се отнася до локалния TCP стек, а не към сървъра. Във всички примери, доставени с Indy, стандартният трик за работа с TIdTcpClient е анкета на таймер (ReadLn, ReadInteger и т.н.). Например, веднъж на всеки 200 милисекунди. Не забравяйте да поставите TIdAntifreeze на формуляра, по един на приложение, в противен случай формулярът ще "замръзне", защото Indy сокетите работят в блокиращ режим. Ако използвате TIdTcpServer и искате да нарисувате нещо върху формуляри чрез събитието OnExecute, тогава не забравяйте да направите Synchronize() или да използвате TIdSync за това. Същият принцип важи и за работата с базата данни. Създайте/унищожете екземпляр на модул с данни при всяка заявка или използвайте единичен модул с данни, като зададете критични секции, или създайте набор от модули с данни и регулирайте тяхното издаване към нишки чрез семафори. По-точно, не модули за данни, а набори от dbconnection + dbqueries.
alienserg (6/14/04 02:44 AM) [27] >Това съобщение достига местоназначението си и седи в TCP стека и >чака клиента там да го анкетира, като изпълни ReadLn >например.
Клиентът все още трябва да анкетира сървъра. Тогава можете да направите нещо подобно: клиентът (на таймер) анкетира сървъра за ново съобщение за него. client1.SendCmd("numb"); if client1.LastCmdResult.Text.Text = "ok" then readin(buf); Server. var mess: boolean; procedure TForm1.Server1Command1numb(ASender: TIdCommand); begin if mass = true then begin asender.Thread.Connection.WriteLn(ok); asender.Thread.Connection.WriteLn("желан низ); end else begin exit; end;
В else throw asender.Thread.Connection.WriteLn("no"); в клиентски манипулатор: случай ако client1.LastCmdResult.Text.Textof "ok":readin(buf); "no":exit;
if client1.LastCmdResult.Text.Text = "ok" then променете на if client1.readln = "ok" then
Когато TIdTcpClient извърши ReadLn, той осъществява достъп до вътрешния буфер на Indy. Следователно, четейки без забавяне (без да чакате изпращане до сървъра), човек може лесно да прочете собственото си съобщение, изпратено до сървъра от същия клиент преди това чрез TIdTcpClient.WriteLn!
Петров (15.06.04 13:31) [31]
буферите за ReadLn и WriteLn са различни.FInputBuffer: TIdManagedBuffer; FWriteBuffer: TIdSimpleBuffer;