TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim)

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim)

Mesaj gönderen erkan1525 »

Kısakesecem üstadlar...
TTcpClient, TTcpServer nesnelerini kullanarak iki program arasında mesaj alıp göndermek istiyorum.
Serverda portu açıyor ve client de bağlanıyor ama tek bir harf bile gönderemiyorum.

Serverda.
TForm1.S1Accept olayı sadece ilk bağlantı sağlandığında çalışıyor ondan sonra tok yok.

Client de
TForm2.C1Receive olayı hiç mi hiç çalışmıyor.

Veri göndermek için
c1.Sendln(edit1.Text); kodunu kullanıyorum...

KAYNAK KODLAR

SERVER

Kod: Tümünü seç

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Web.Win.Sockets, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    S1: TTcpServer;
    Button2: TButton;
    procedure FormShow(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure S1CreateHandle(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure S1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
    procedure S1DestroyHandle(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses
unit2;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  s1.Sendln(edit1.Text);
  memo1.Lines.Add('BEN - > '+ edit1.Text);
  memo1.SelStart:=length(memo1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  s1.Active:=false;
  s1.Active:=true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  form2.Show;
end;

procedure TForm1.S1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
  var
  gveri:string;
begin
  s1.Accept;
  memo1.Lines.Add('---');
  s1.ReceiveBuf(gveri,200);
  memo1.Lines.Add('KARŞI TARAF - > '+ gveri);
end;

procedure TForm1.S1CreateHandle(Sender: TObject);
begin
  memo1.Lines.Add(datetimetostr(now)+' - > Dinleme başladı.');
end;

procedure TForm1.S1DestroyHandle(Sender: TObject);
begin
  memo1.Lines.Add('Hareket');
end;

end.
CLIENT

Kod: Tümünü seç

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Web.Win.Sockets, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    C1: TTcpClient;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure C1Connect(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure C1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  c1.Sendln(edit1.Text);
  memo1.Lines.Add('BEN - > '+ edit1.Text);
  memo1.SelStart:=length(memo1.Text);
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  c1.Active:=false;
  c1.RemotePort:='1525';
  c1.RemoteHost:='localhost';
  c1.Connect;
end;

procedure TForm2.C1Connect(Sender: TObject);
begin
  memo1.Lines.Add(datetimetostr(now)+' - > Bağlantı sağlandı. ' )
end;

procedure TForm2.C1Receive(Sender: TObject; Buf: PAnsiChar;
  var DataLen: Integer);
  var
  gveri:string;
begin
  memo1.Lines.Add('---');
  c1.ReceiveBuf(gveri,datalen);
  memo1.Lines.Add('KARŞI TARAF - > '+ gveri);
end;

end.
Delphi Sürümü XE2
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2381
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen freeman35 »

demosu varsa demosunu incele, windows firewall kesiyor olabilir. Accept bağlantıyı kabul eden kısım, gerekirse bağlantıyı engelleyebilmek için, daha sonrası receive yani bağlı olanlardan gelenler burayı tetikler. ayrıca aynı porta sadece bir bağlantı yapabilirsin, yani 1525 portuna bağlantı varsa senin kullanımının dışındada olabilir, bağlanamazsın.
procedure TForm1.S1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
...
s1.Accept;--> bu ne iş yapar? kendi içinde kendinimi tetikliyor?
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen erkan1525 »

Visual basicde çok uğraştığım için port olaylarını biliyorum. Freeval falan engel oluyor.

Normalde accept olayında dediğin doğru VB ye göre burada bağlantının kabul ediliyor olması lazım. VB de bu olaya "winsock.Accept RequestID" kodunu yazıyorduk. Ama burda farklı örneklerde burada veri olınmış bende örneklerden giderek böyle yaptım.

Aslında çalışan düzgün bir örnek bulamadım. Örnekler hep dephi 7 de ve XE sürümlerinde eski sürümlerde kullanılan Soket araçları birbirinden farklı.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2381
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen freeman35 »

muhtemelen Freeval değildir o firewall dur. delphi 7 ile xe arasında socket lerin bağlanma ve veri gönderme sinde senin açından tek değişiklik unicode farkıdır. Onun haricinde değişen kodlar, kullanım şeklini değiştirmemiştir. vb ile pascal kullanımları farklıdır, o yüzden "orda böleydi" işini unutmazsan pascal da çok zorluk çekersin, vb yi unut. örnek:
"VB ye göre burada bağlantının kabul ediliyor olması lazım." dediğin yerde, pascal accept eventini tetiklediyse, sana bağlantının kabul edildiğini ve gelen bağlantının bilgileri verir (TCustomIpClient), yani bağlantı işlem gerçekleşmiş demektir.
delphi içinde gelen demolara çalışmıyor olabilir, ama bu kesinlikle senin yada sisteminle alaklı olduklarını sakın unutma
Kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
PROGRAMADOR
Üye
Mesajlar: 239
Kayıt: 04 Oca 2008 01:53
Konum: Karşıyaka/İzmir

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen PROGRAMADOR »

Kod: Tümünü seç

unit frmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Sockets, StdCtrls,Classes2;

type
  TUser=Class
    private
      //ClientSocket: TCustomIpClient;
      Nick:String;
      ip:string;
      port:string;
    public
      function GetName : string;
end;    

type
  TForm1 = class(TForm)
    btnBaslat: TButton;
    MyServer: TTcpServer;
    Memo1: TMemo;
    Label1: TLabel;
    txtPort: TEdit;
    lbUsers: TListBox;
    MyClient: TTcpClient;
    procedure btnBaslatClick(Sender: TObject);
    procedure MyServerAccept(Sender: TObject;
      ClientSocket: TCustomIpClient);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Users:TMylist;



implementation

{$R *.dfm}

{
chr(1)  //giriş yapıyorum
chr(2)  //kanaldaki kullanıcı listesi
chr(10)  //sohbet yazısı


//chr(1)+nick+chr(1)+ip+chr(1)+port //login
//chr(2)+nick+chr(2)+ip+chr(2)+port
//chr(10)+nick+chr(10)+yazı ///yazı


}

procedure TForm1.btnBaslatClick(Sender: TObject);
begin
  MyServer.Active:=false;
  MyServer.LocalPort:=txtPort.Text;
  MyServer.Active:=true;
  Memo1.Lines.Add('Server '+MyServer.LocalPort+' portu ile başlatıldı!');
end;

procedure TForm1.MyServerAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
s,nick:string;
newuser,currentuser:TUser;
str:string;
fc:string;//ilk karakter
text:string;
i:integer;
sck:TCustomIpClient;
clientport:string;
begin
try
// Memo1.Lines.Add('Rem Host: ' +
//    ClientSocket.LookupHostName(ClientSocket.RemoteHost) + ' (' + ClientSocket.RemoteHost + ')');
  s := ClientSocket.Receiveln;

  
  fc :=copy(s,1,1);
  delete(s,1,1);


  if fc=chr(1) then begin //nicki kontrol et
     Nick:=copy(s,1,pos(chr(1),s)-1);
     delete(s,1,pos(chr(1),s));
     clientport:=s;
     newUser:=TUser.Create;
     //newUser.ClientSocket:=ClientSocket;
     newUser.Nick:=Nick;
     newUser.port:=clientport;
     newUser.ip:=ClientSocket.RemoteHost;
     Users.Add(newUser);
     lbUsers.Items.Add(Nick+', '+ClientSocket.RemoteHost+', '+clientport);
     Memo1.Lines.Add(nick+' sohbete katıldı');
      for i:=0 to users.Count-1 do begin
        currentuser:=Users[i];
        MyClient.RemoteHost:=ClientSocket.RemoteHost;
        MyClient.RemotePort:=clientport;
        try
          if MyClient.Connect then
            MyClient.Sendln(chr(2)+nick+chr(2)+currentuser.ip+chr(2)+currentuser.port);
        except
          MyClient.Disconnect;
          Continue;
        end;
        MyClient.Disconnect;
      end;
      for i:=0 to users.Count-1 do begin
        currentuser:=Users[i];
        MyClient.RemoteHost:=currentuser.ip;
        MyClient.RemotePort:=currentuser.port;
        try
          if MyClient.Connect then
            MyClient.Sendln(chr(1)+nick+chr(1)+ClientSocket.RemoteHost+chr(1)+clientport);
          except
            MyClient.Disconnect;
            continue;
          end;
         MyClient.Disconnect;
      end;
  end else if fc=chr(10) then begin //yazı gönderme
     Nick:=copy(s,1,pos(chr(10),s)-1);
     delete(s,1,pos(chr(10),s));
     text:=s;
     Memo1.Lines.Add(nick+' > '+text);
      for i:=0 to users.Count-1 do begin
        currentuser:=Users[i];
        //user.Clientsocket.sendln(chr(1)+nick);
        MyClient.RemoteHost:=currentuser.ip;
        MyClient.RemotePort:=currentuser.port;
        try
          if MyClient.Connect then
            MyClient.Sendln(chr(10)+nick+chr(10)+text);
          except
            MyClient.Disconnect;
            continue;
          end;
         MyClient.Disconnect;
      end;

  end;

except
end;



end;

{ TUser }

function TUser.GetName: string;
begin
  Result:=self.Nick;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Users.free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Users:=Tmylist.Create;
end;



end.
Yukarıdaki kod gayet iyi çalışıyor. Lütfen tmylist nedir diye sormayın. tlist'e benzer pointer tutan bir sınıf. Generics kullanıyorsanız tlist<pointer> ya da tlist<TUser> şeklinde tlist'i kullanabilirsiniz. Kodun mantığını anlamınız yeterli. chr (0), chr(1) ve chr(2)'ler protokolle ilgilidir. örneğin giriş isteği, yazı gönderme, port bilgisi gönderme. verileri çekerken parse edilmesi gerekiyor.

İyi çalışmalar.
In dubio pro reo...
Şüpheden sanık/özgürlük yararlanır...
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen erkan1525 »

Cevaplara hayret ettim.
İngilizce kaynaklardan okuduğum kadarıyla TTcpClient, TTcpServer te veri geldiğinde bir olayı tetikleyecek bir özellik yokmuş. Bunun için Clientsoket ve server soket kullanmam gerekliymiş. XE sürümleri için olan clientve server soketler varsayılan olarak yüklenmiyor. Kurulumdan sonra combonent instal kısmından ufak bir yükleme yapmak gerekiyor. Yani yeni sürümlerdede eskisi gibi ClientSoket ve ServerSoket kullanmak gerekiyor. Aynı sıkıntıları yaşayan arkadaşlar için yazdım.
Kullanıcı avatarı
AliZairov
Üye
Mesajlar: 341
Kayıt: 06 Nis 2012 03:09
Konum: Azerbaycan, Bakü
İletişim:

Re: TTcpClient, TTcpServer ile basit mesajlaşma. (Kirizdeyim

Mesaj gönderen AliZairov »

Iyi akşamlar. Hiç İndy uğraşma. Direk DataSnap kullan. En kolay onunla olur ben yaptım kendime gereken projeyi. Hemde XE üzeri versiyonlarda mobil cihazlarda destekliyo o da iyi tarafı.
Cevapla