indy 10 yardım!

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

yaf bu indy 10 da idtcpclient ın neden onreceive gibi bir eventı yok.workbegin filanda pek bi işe yaramıyor

readln #13 #10 istiyor okumayı bitirmek için
readstring ne kadar byte okumak istediğimi soruyor bana ki eksik veya fazla verirsek readtimeout a düşüyor
allahım ya bu delphinin derdi bitmezmi ya.Şu ünv.sıralarında delphi öğreneceğime koynumda taş besleseydim dicem ama uymucak
uysada uymasada :d

vakit ayırıp cevap verebilecek arkadaşlara içten saygılarrr.

Ya birde şu var.idtcpclient nesnesinde gönderdiğim texte cevap geldiğinde tetiklenecek bir olayda bulamadım.
tcpclient'taki gibi onreceive bir olay yok
idtcpclient.iohandler.writeln('abc');
dedim sonrada bana cevap döndüğünde tetiklenecek bir event yokmudur???

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Re: indy 10 yardım!

Mesaj gönderen Battosai »

İndy geliştiricileri gerekli görseydi dediğin event ları eklerdi....Bu durumda kotrolü kendin yapcaksın...bir değer gönderdiğin eğer cevap gelmiyorsa boolean false döndürürsün olur biter...mevcut özellikler ile işini göreceğin kanaatindeyim....
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

Readln ile işimi görmem mümkün deil.Neden derseniz bana gelecek veride illaki bir sonlandırıcı karakter aramam benim programım açısından mantıklı deil.readstring ilede gelecek verinin boyutunu bilmiyorum buda benim işimi çözmüyor.
geriye readstream kalıyor ki bu genelde dosya aktarımlarında kullanıldığını farkettim.
Birde onreceive olayının olmaması beni timer kullanmaya mecbur bırakıyor sanki.Timerda sonuç itibariyle programın çalışmasındaki performansı düşürdüğü gibi misal her atışında 10 byte oku gibi birşey demem lazım..
Mesele çok büyüyor gözümde.
Daha önceden indy 10'la çalışan bir arkadaşın bana daha çok yardımcı olacağını düşünüyorum.


SAYGILAR..

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
undefined
Moderator
Mesajlar: 565
Kayıt: 06 Eki 2003 12:01
Konum: Bursa
İletişim:

Re: indy 10 yardım!

Mesaj gönderen undefined »

Eğer senkron, yani komut-cevap şeklinde bir iletişim protokolün varsa her write'tan sonra read ile cevabı alman gerekir.
Fakaat, indy blocking socket kullanır yani okuma işlemi gerçekleşene kadar program donar. Bunun için işlemler okuma ve yazmayı thread içinden gerçekleştrimen gerekir bu yüzden Thread kullan. Timer iyi bir çözüm değil.

Gelen veriler bir bufferda toplanır, hangi read koşuluyla okuma yaptıysan indy, bufferdaki verileri bu koşulu karşılayana kadar sana döndürmez. O yüzden sen nasıl bir verinin geleceğini bilmen lazım. Kod yazarken doğaçlama bir sisteme göre değil bir protokole göre soket programlası yapmalısın. Binary bir protokol kullanıyorsan, sonlandırma karakterini unut, çünkü verinin içinde senin belirlediğin sonlandırma karakteri geçebilir. Text tabanlı protokollerde binary veri geçirmek için Base64 kodlaması kullanılıyor fakat buda veriyi büyütüyor. O yüzden şöyle bir protokol tasarlayabilirsin. ilk önce Writeinteger ile göndereceğinin verinin boyutunu gönder sonra karşısı kendini buna göre ayarlasın ve okuma yapsın. Tabi bunun için karşısı readinteger ile veriboyutunu beklemesi gerekir. Bu yüzden iletişimin mutlaka bir protokol mantığı içinde gerçekleşmesi lazım.

Kolay gelsin...
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

Şimdi öncelikle haberleşeceğim serverlar elektronik cihazlar.Çok fazla önemi olmasada söylememde yarar olacağını düşündüm.
Tek hat üzerinde 100 e yakın cihaz olduğu zaman butür biryöntemin başarılı olabileceği konusunda tedirginliklerim var.

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

herkes onwork eventından bahsederken progresbar örneği veriyor.Arkadaşlar veri geldiği halde
yani ben veriyi yazdıktan sonra
memo.text:=idtcpclient.iohandler.readstring(16) ile veriyi okuyorum ama onwork neden tetiklenmiyor veri olduğu halde???

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
undefined
Moderator
Mesajlar: 565
Kayıt: 06 Eki 2003 12:01
Konum: Bursa
İletişim:

Re: indy 10 yardım!

Mesaj gönderen undefined »

indy'nin help'inden alıntı:
OnWork is a public TWorkEvent property in TIdIOHandler that is the event handler signalled when a read or write method is called for the IOHandler. OnWork is generally used to control the update of progress indicators or GUI components.

The work mode indicates the operation performed and the notification sent to OnWork, and can contain one of the following values:
OnWork'ün işi sadece Okuma/yazma işlemlerinin yapıldığını haberdar etmek. Bu işlemleride sen yapıyorsun zaten. Yapmazsan haber vermez.
Indy'de veriyi okumanın tek yöntemi IOHandler aracılığı ile sockete read yapmaktır. Önceden de dediğim gibi bu operasyonlar blocking'dir. Thread veri gelene kadar durur. Eğer ana threadde bu operasyonları yaparsan gui donar. Indy'nin çalışma mantığı budur bu sana uymuyorsa ICS component paketi gibi asenkron I/O kullanan çözümleri dene. Onlar blocking socket kullanmazlar.
Sistemde 100 makina olacak falan demişsin, tcpclient tek bağlantı kurmak için kullanılır, biraz detaya girersen daha yardımcı olmaya çalışırım, diğer türlü ne yaptığını bildiğinden şüphe ediyorum.
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

Sistem şöyle
Bir adet ip numarasına sahip bir server cihaz ve bu kendisine bağlı yaklaşık 100 e yakın cihazla haberleşiyor.Daha dorusu bu bir arakart ben ona komutlarımı gönderiyorum oda bana aldığı cevapları.
Eğer ki sistemimiz şöle olsaydı herhangi bir problem yoktu mesela
ben bu server cihaza kendine bağlı 68.cihaza şu komutu gönder deseydim ve oda aldığı cevabı bana iletseydi
ben şu şekilde bir ,işlemler yırtabilirdim.
idtcpclient1.writeln('abc');
idtcpclient.iohandler.checkfordataonsource(250)--Bu arada bu olayıda dün farkettim hani daha önce readstringte byte sayısı vermek zorundayım bende gelecek datanın kaç byte olduğunu bilmiyorum byte sayısını değişken yazmak zorundayım demiştim.İşte buna çözüm buymuş.bu komutu yazmaddığım zaman araya ,inputbuffer.size 0 geliyor ama bu komutu yazdığımda inputbuffer.size tam istediğim gibi receive olan byte sayısı kadar oluyor...Neyse bir alt satıra geçim
idtcpclient.iohandler.readstring(idtcpclient.iohandler.inputbuffer.size);
ama bu ben veri yazdığımda bir cevabı beklediğimde işe yarar..
Şimdiki sorun ise şu.server cihaza bağlı herbir cihaz 3 dk.da bir server cihaza veri gönderiyor.Tabikii oda bana gönderiyor.Bu durumda da ben herdata geldiğinde birşekilde uyarılmam lazım.Buda bana her data geldiğinde bir olayın tetiklenmesiyle olması lazım.Yaptığım araştırmalarda genelde söyledikleri çözüm yolu aynen senin dediğin gibi ya timer ile periyodik okuma yada thread.newswhat ta newsgroupta da herifler aynen benim yaşadığım problemi yaşamışlar.ve cevap gene aynı.
Umarım anlatabilmişimdir...

Saygılar,Teşekkürler..

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

kanal yöntemiyle bu işi çözdüm bağlantı oluştuğunda kanalımda çalışmaya başlıyor ve gelen data varsa memoya basıyorum.
Peki neden kanal kullanmak zorunda kalıyoruz.Yani bu yöntem daha mı iyidir.Neden onreceive gibi bir olay yok ki.
İşi çözdüm sonuçta ama genede merak ettim??

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Kullanıcı avatarı
bulutsuzluk_35
Üye
Mesajlar: 124
Kayıt: 06 Eki 2007 04:14
Konum: İzmir-Ankara-İstanbul-Antalya
İletişim:

Re: indy 10 yardım!

Mesaj gönderen bulutsuzluk_35 »

Kod: Tümünü seç

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Sockets, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, ComCtrls, IdAntiFreezeBase, IdAntiFreeze,IdException,
  IdIntercept, IdTelnet,IdGlobal;

type
  TForm1 = class(TForm)
    GroupBox2: TGroupBox;
    lbLightValue: TLabel;
    lbPort: TLabel;
    edIsikDeger: TEdit;
    edPort: TEdit;
    Label1: TLabel;
    Edit1: TEdit;
    imgIsaret: TImage;
    imgHIZ: TImage;
    smgBos2: TImage;
    smgBos1: TImage;
    smgElli: TImage;
    smgYetmis: TImage;
    smgDoksan: TImage;
    smgUnlem: TImage;
    smgDuz: TImage;
    smgCarpi: TImage;
    smgSol: TImage;
    smgSag: TImage;
    edHizAdres1: TEdit;
    edIsaretAdres1: TEdit;
    memoDonenAsc: TMemo;
    lbDonenMemo: TLabel;
    edDonenChar: TEdit;
    Button1: TButton;
    Label2: TLabel;
    Label3: TLabel;
    IdTCPClient1: TIdTCPClient;
    Button2: TButton;
    ProgressBar1: TProgressBar;
    IdAntiFreeze1: TIdAntiFreeze;
    Timer1: TTimer;
    Timer2: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure IdTCPClient1Disconnected(Sender: TObject);
    procedure IdTCPClient1Connected(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure smgSagDblClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
type
TReadingThread = class(TThread)
private
  FConn: TIdTCPConnection;
protected
  procedure AfterConstruction; override;
  procedure Execute; override;
public
  constructor Create(AConn: TIdTCPConnection); reintroduce;
end;
var
  ReadingThread: TReadingThread = nil;

var
  Form1: TForm1;
  a:integer;
  procedure PortaYaz(Adres:Integer;Deger:Char);

implementation

{$R *.dfm}
constructor TReadingThread.Create(AConn: TIdTCPConnection);
begin
  inherited Create(True);
  FConn := AConn;
end;

procedure TReadingThread.AfterConstruction;
begin
  Resume;
end;

procedure TReadingThread.Execute;
var
  S: String;
begin
  while not Terminated do
  begin
    S := FConn.IOHandler.ReadLn;
    if S<>'' then
    begin
    Form1.memoDonenAsc.Text:=S;
    S:='';
    end;
  end;
end;
procedure PortaYaz(Adres:Integer;Deger:Char);
var
i,checksum:integer;
Protokol:String;
begin
  checksum:=0;
  checksum:=  ...;
  Protokol:=...;
  Form1.IdTcpClient1.IOHandler.WriteLn(Protokol);
end;
//bağlanma olayı
procedure TForm1.Button1Click(Sender: TObject);
begin
  try
  IdTcpClient1.Connect(Edit1.Text,StrToInt(edPort.Text));
  ReadingThread := TReadingThread.Create(IdTCPClient1);
  Except
  Label3.Caption:='Bağlanılmadı!!!';
  end;
end;
//Porta yazma
procedure TForm1.smgSagDblClick(Sender: TObject);
begin
  memoDonenAsc.Text:='';
  edDonenChar.Text:='';
  if Sender = smgSag then
  PortaYaz(StrToInt(edIsaretAdres1.Text),'R');
  if Sender = smgSol then
  PortaYaz(StrToInt(edIsaretAdres1.Text),'L');
  if Sender = smgDuz then
  PortaYaz(StrToInt(edIsaretAdres1.Text),'D');
  if Sender = smgCarpi then
  PortaYaz(StrToInt(edIsaretAdres1.Text),'M');
  if Sender = smgElli then
  PortaYaz(StrToInt(edHizAdres1.Text),'F');
  if Sender = smgYetmis then
  PortaYaz(StrToInt(edHizAdres1.Text),'S');
  if Sender = smgDoksan then
  PortaYaz(StrToInt(edHizAdres1.Text),'N');
  if Sender = smgUnlem then
  PortaYaz(StrToInt(edHizAdres1.Text),'C');
end;
//disconnect olayı
procedure TForm1.Button2Click(Sender: TObject);
begin
begin
  if Assigned(ReadingThread) then
    ReadingThread.Terminate;
  try
    IdTCPClient1.Disconnect;
  finally
    if Assigned(ReadingThread) then
    begin
      ReadingThread.WaitFor;
      FreeAndNil(ReadingThread);
    end;
  end;
end;
end;


procedure TForm1.IdTCPClient1Connected(Sender: TObject);
begin
Label3.Caption:='Bağlanıldı...';
end;

procedure TForm1.IdTCPClient1Disconnected(Sender: TObject);
begin
Label3.Caption:='Bağlantı kesildi!!';
end;

end.
Arkadaşlara örnek olması açısından yararı olacağını düşünüyorum.Burada gene readln kullanıldı yani #13#10 gelene kadar okuma yaptı kanal ama siz burda readstring(Fconn.iohandler.inputbuffer.size) ile sonlandırıcı karaktere kadar değilde receive olan byte kadar okuyabilirsiniz.

Kod: Tümünü seç

try
  try
    inc(Bilgi);
  except
    sabir;
  end;
finally
  inc(Mutluluk);
end;
Cevapla