Mengirim pesan Delphi. Delfi

Mengirim pesan Delphi. Delfi

Urutan pemrosesan pesan di Delphi
Semua kelas Delphi memiliki mekanisme penanganan pesan bawaan yang disebut penangan pesan. Sebuah kelas menerima pesan dan memanggil salah satu dari sekumpulan metode yang ditentukan bergantung pada pesan yang diterima. Jika metode terkait tidak ditentukan, maka pengendali default akan dipanggil. Secara lebih rinci, mekanisme ini bekerja sebagai berikut.

Setelah pesan diterima, sistem pesan VCL melakukan banyak pekerjaan awal untuk memprosesnya.

Seperti disebutkan di atas, pesan awalnya diproses dengan metode TApplication.ProcessMessage, yang memilihnya dari antrian di loop pesan utama. Pada saat yang sama, ia memeriksa konten bidang FOnMessage (sebenarnya, ia memeriksa keberadaan penangan untuk acara OnMessage) dan, jika tidak kosong, maka memanggil penangan untuk acara ini, dan jika bidang tersebut kosong (Nil), lalu memanggil fungsi API DispatchMessage(Msg). Hal ini tidak terjadi saat mengirim pesan.

Jika pengendali kejadian OnMessage tidak ditentukan, fungsi API DispatchMessage dipanggil untuk memproses pesan yang diterima, yang meneruskan pesan tersebut ke prosedur jendela utama.

Mari pertimbangkan siklus pemrosesan pesan setelah pesan tersebut tiba di jendela utama komponen. Urutan pemrosesan pesan ditunjukkan pada gambar berikut:

Terlihat bahwa pesan dikirimkan ke MainWndProc, lalu ke WndProc, lalu ke Dispatch, lalu ke DefaultHandler.

Delphi menyediakan metode non-virtual utama MainWndProc(Var Message: TMessage) untuk setiap jendela komponen. Ini berisi blok penanganan pengecualian, meneruskan struktur pesan dari Windows ke metode virtual yang ditentukan dalam properti WindowProc. Namun, metode ini menangani pengecualian apa pun yang terjadi selama pemrosesan pesan dengan memanggil metode HandleException aplikasi. Mulai dari titik ini adalah mungkin untuk menyediakan perlakuan khusus pesan, jika diperlukan oleh logika program Anda. Biasanya pada titik ini pemrosesan dimodifikasi untuk mencegah terjadinya pemrosesan VCL standar.

Secara default, nilai properti WindowProc suatu objek diinisialisasi ke alamat metode virtual WndProc. Selanjutnya, jika tidak ada pencegat pesan terdaftar dari tipe TWindowHook, WndProc memanggil metode virtual TObject.Dispatch, yang menggunakan bidang Msg dari struktur pesan masuk, menentukan apakah pesan ini ada dalam daftar penangan pesan untuk dari objek ini. Jika objek tidak memproses pesan, daftar penangan pesan leluhur akan diperiksa. Jika metode seperti itu akhirnya ditemukan, maka disebut sebaliknya, metode virtual DefaultHandler dipanggil.

Akhirnya, pesan tersebut mencapai prosedur pemrosesan yang sesuai, di mana pemrosesan yang dimaksudkan untuk pesan tersebut dilakukan. Dengan menggunakan kata kunci Warisan itu selanjutnya dikirim untuk diproses oleh leluhur. Pesan tersebut kemudian juga masuk ke metode DefaultHandler, yang melakukan pemrosesan pesan terakhir dan meneruskannya ke prosedur DefWindowProc (DefMDIProc) untuk pemrosesan standar Windows.

Memproses pesan dengan komponen Delphi
Dengan demikian, deskripsi singkat Urutan pemrosesan pesan adalah sebagai berikut. Semua pesan awalnya melewati metode yang alamatnya ditentukan di properti WindowProc. Secara default ini adalah metode WndProc. Setelah itu mereka dipisahkan dan dikirim sesuai dengan metode pesannya masing-masing. Pada akhirnya, mereka bertemu lagi dalam metode DefaultHandler, jika mereka tidak diproses sebelumnya atau penangan yang diwarisi (Diwarisi) dipanggil di penangan. Oleh karena itu, komponen Delphi mempunyai kemampuan berikut untuk menangani pesan:
a) Sebelum penangan pesan melihat pesan tersebut. Dalam hal ini, Anda perlu mengganti alamat metode di properti WindowProc atau mengganti metode TControl.WndProc.
Properti WindowProc dideklarasikan sebagai berikut:

Tur Metode Kedua= Prosedur(Pesan Var: Pesan) Dari Objek;
Milik WindowProc: Metode TWnd;

Faktanya, dengan menggunakan properti WindowProc, Anda dapat membuat metode bertipe TWndMethod dan mengganti sementara metode asli dengan metode yang dibuat, namun karena alamat metode di properti WindowProc tidak disimpan, Anda harus menyimpan alamat aslinya terlebih dahulu. Metode WndProc agar nanti bisa direstore.

OldWndProc: Metode TWnd;
procedure NewWndProc(var Pesan: TMessage);
procedure TForm1.NewWndProc(var Pesan: TMessage);
var Ch: arang;
mulai
jika message.Msg= WM_MOUSEMOVE lalu mulai
Sunting1.Teks:='x='+inttostr(message.LParamLo)+', y='+inttostr(message.LParamHi);
akhir
lain WndProc(Pesan);
akhir;

prosedur TForm1.FormCreate(Pengirim: TObject);
mulai
OldWndProc:=WindowProc;
akhir;

prosedur TForm1.CheckBox1Click(Pengirim: TObject);
mulai
Jika CheckBox1.Checked maka WindowProc:= NewWndProc
lain WindowProc:= OldWndProc;
akhir;

b) Di dalam metode pesan yang sesuai.
Mari kita berikan contoh serupa lainnya.
Menggunakan pesan yang dikirim ke komponen untuk menggambar ulang WMPAINT.

Di kelas TForml, kami akan mendeklarasikan metode ini untuk tujuan menimpanya dan menyajikan implementasi metode pesan yang diganti:

Mendatang TForml=Kelas(TForm)
… // Semua deklarasi lain yang diperlukan
Terlindung
Prosedur WMPaint(Pesan Var: TWMPaint); Pesan WM_PAINT; Akhir;
Prosedur TForml.WMPaint(Pesan Var: TWMPaint); Mulai
Jika CheckBox1.Checked Kemudian ShowMessage('O6pa6ot message!');
Diwarisi;
Akhir;

Saat mengganti penangan pesan tertentu, sebaiknya panggil Inherited untuk melakukan pemrosesan pesan dasar yang diperlukan Windows.

c) Setelah masing-masing metode yang sesuai dengan pesan melihatnya.

Dalam hal ini, perlu untuk mengganti DefaultHandler.

prosedur DefaultHandler(var Pesan); mengesampingkan;
prosedur TForm1.DefaultHandler(var Pesan);
var i: bilangan bulat;
mulai
jika Kardinal(Pesan)=WM_defh maka
untuk i:= 0 hingga 10 dimulai
berbunyi;
tidur(100);
akhir
kalau tidak
diwariskan;
akhir;

prosedur TForm1.Button5Click(Pengirim: TObject);
mulai
Kirim Pesan(Menangani,WM_defh,0,0);
akhir;

Hubungan antara pesan dan peristiwa
Banyak kejadian VCL Delphi yang berhubungan langsung dengan pesan Windows. DI DALAM sistem bantuan Delphi pertandingan ini terdaftar. Mereka disajikan pada Tabel 1.

Tabel 1

Acara VCLpesan WindowsAcara VCLpesan Windows
AktifkanWM_AKTIFKANDiKeyPressWM_CHAR
DiKlikWM_LBUTTONDOWNOnKeyUpWM_KEYUP
DiBuatWM_CREATEDi CatWM_CAT
DiDblKlikWM_LBUTTONDBLCLKPada Ubah UkuranWM_SIZE
DiKeyDownWM_KEYDOWNPengatur WaktuWM_TIMER

Anda tidak boleh membuat penangan pesan jika ada peristiwa yang telah ditentukan sebelumnya. Dalam kasus seperti itu, masuk akal untuk menggunakan penanganan peristiwa karena batasannya lebih sedikit.

Saat mengembangkan aplikasi, mungkin ada situasi di mana aplikasi perlu mengirim pesan ke dirinya sendiri atau ke aplikasi pengguna lain. Beberapa orang mungkin bingung dengan pernyataan sebelumnya: mengapa aplikasi mengirimkan pesan ke dirinya sendiri padahal aplikasi tersebut hanya dapat memanggil prosedur yang sesuai? Ini pertanyaan bagus, dan ada beberapa jawabannya. Pertama, penggunaan pesan merupakan mekanisme untuk mendukung polimorfisme nyata, karena tidak memerlukan pengetahuan apa pun tentang jenis objek yang menerima pesan. Dengan demikian, teknologi pesan memiliki kekuatan yang sama dengan mekanisme metode virtual, namun dengan fleksibilitas yang jauh lebih besar. Kedua, pesan memungkinkan pemrosesan opsional - jika objek penerima tidak memproses pesan masuk, maka tidak ada hal buruk yang akan terjadi. Dan ketiga, pesan memungkinkan penyiaran ke banyak penerima dan mendengarkan secara paralel, yang cukup sulit diterapkan menggunakan mekanisme panggilan prosedur.

Menggunakan pesan dalam aplikasi

Membuat aplikasi mengirim pesan ke dirinya sendiri sangatlah sederhana - cukup gunakan fungsinya antarmuka API Win32 SendMessage() atau Post-Message(), atau metode Perform(). Pesan harus memiliki ID dalam rentang WM_USER+100 hingga $7FFFF (Windows mencadangkan rentang ini untuk pesan pengguna). Misalnya: konst

SX_MYMESSAGE = WM_USER+100;

SomeForm.Perform(SX_MYMESSAGE, 0, 0);

SendMessage(SomeForm.Handle, SX_MYMESSAGE, 0, 0);

PostMessage(SomeForm.Handle, SX_MYMESSAGE, 0, 0);

Kemudian, untuk mencegat pesan ini, buat prosedur pengendali reguler yang melakukan tindakan yang diperlukan pada formulir:

TForm1 = kelas(TForm)

procedure SXMyMessage(var Pesan: TMessage); pesan SX_MYMESSAGE;

prosedur TForm1.SXMyMessage(var Pesan: TMessage);

MessageDlg('Dia mengubahku menjadi kadal air!',

mtInformasi, , 0);

Seperti yang Anda lihat dari contoh, ada sedikit perbedaan dalam pemrosesan pesan khusus dan pesan Windows standar. Mereka terdiri dari penggunaan pengidentifikasi dalam rentang WM_USER+100 ke atas, serta memberi setiap pesan nama yang mencerminkan maknanya.

Jangan pernah mengirim pesan dengan nilai WM_USER lebih besar dari $7FFF kecuali Anda benar-benar yakin bahwa penerima mampu memproses pesan tersebut dengan benar. Karena setiap jendela dapat secara mandiri memilih nilai yang digunakannya, bug kecil kemungkinan besar akan terjadi kecuali tabel ID pesan dibuat terlebih dahulu untuk digunakan oleh semua pengirim dan penerima pesan.

Pesan antar aplikasi

Jika Anda perlu bertukar pesan antara dua aplikasi atau lebih, Anda harus menggunakan fungsi API RegisterWindowMessage(). Metode ini memastikan bahwa untuk jenis pesan tertentu, setiap aplikasi akan menggunakan jenis pesan yang sama nomor pesan(nomor pesan).

Fungsi RegisterWindowMessage() mengambil string sebagai parameter

diakhiri dengan karakter null dan mengembalikan pengenal dalam rentang $C000 - $FFFF untuk pesan baru. Artinya, memanggil fungsi ini dengan string yang sama sebagai parameter di aplikasi apa pun akan cukup untuk menjamin nomor pesan yang sama di semua aplikasi yang berpartisipasi dalam pertukaran. Manfaat lain dari fitur tersebut adalah sistem memastikan bahwa pengidentifikasi yang ditetapkan untuk string tertentu adalah unik. Ini memungkinkan Anda mengirim pesan siaran ke semua jendela yang ada di sistem tanpa takut akan pesan yang tidak diinginkan. efek samping. Kerugian metode ini ada beberapa kerumitan dalam memproses pesan tersebut. Masalahnya adalah ID pesan hanya diketahui saat aplikasi sedang berjalan, sehingga prosedur penanganan pesan standar tidak dapat dilakukan. Untuk menangani pesan seperti itu, Anda perlu mendefinisikan ulang metode standar Kontrol WndProc() atau DefaultHandler() atau prosedur kelas jendela terkait.

CATATAN

Nomor yang dikembalikan oleh fungsi RegisterWindowMessage() dibuat secara dinamis dan dapat diterima arti yang berbeda cuek Sesi Windows, yang berarti tidak dapat ditentukan sampai program dijalankan.

Pesan siaran

Kelas apa pun yang berasal dari kelas TWinControl memungkinkan Anda menggunakan metode Broadcast() untuk mengirim pesan siaran(pesan siaran) ke kendali mana pun yang merupakan pemiliknya. Teknologi ini digunakan jika Anda ingin mengirim pesan yang sama ke sekelompok komponen. Misalnya, untuk mengirim pesan khusus bernama um_Foo ke semua kontrol milik objek Panel1, Anda bisa menggunakan kode berikut:

Pesan:= UM_FOO;

Kembangkan program yang akan menyediakan antarmuka untuk menggunakan perintah transfer pesan standar Win2000/XP net send. Izinkan pengguna menentukan alamat penerima, teks pesan, dan jumlah pesan yang akan dikirim. Juga menyediakan kemampuan untuk memblokir penerimaan pesan dari komputer lain.

Pengembangan formulir

Membuat proyek baru Delfi. Ubah judul formulir (properti Caption) menjadi Net Sender. Tempatkan tiga komponen kategori Label satu di atas yang lain di sepanjang tepi kiri formulir. Standar dan atur properti Captionnya menjadi Alamat IP:, Pesan:, dan Kuantitas:.

Tempatkan komponen Edit kategori di samping setiap label Standar. Beri nama ip teratas (Properti Nama), dan berikan nilai pada properti Teks 192.168.0.1.; beri nama bidang tengah txt, dan tetapkan properti Teks ke beberapa teks pesan default; Beri nama bidang paling bawah bagaimana, dan atur properti Teks ke 1.

Di bawah komponen yang terdaftar, tempatkan komponen Kotak Centang Kategori Standar. Beri nama aman, atur properti Caption ke Disable Message Reception, dan properti Checked ke True.

Di bagian paling bawah formulir, tempatkan sebuah tombol (komponen kategori Tombol Standar), mengatur properti Caption menjadi Kirim. Kita juga membutuhkan timer (komponen kategori Timer Sistem), yang properti Intervalnya harus disetel ke 10.

Bentuk yang dihasilkan harus sesuai dengan Gambar. 15.1.

Beras. 15.1. Formulir untuk program tujuan pengiriman pesan jaringan lokal

Pengembangan kode program

Pertama-tama, mari kita tulis prosedur bom kita sendiri, yang akan membaca semua pengaturan dan mengirim pesan. Deklarasikan prosedur ini sebagai anggota pribadi kelas formulir:

Kita juga memerlukan variabel global i bertipe integer:

Sekarang mari kita buat implementasi prosedur bom di bagian implementasi:

prosedur TForm1.bom();
jika bagaimana.Teks= "" lalu bagaimana.Teks:= "1";
jika ip.Teks = "" maka ip.Teks:= "127.0.0.1";(jika alamat IP tidak ditentukan, maka kami kirim ke komputer lokal}
WinExec(PChar("kirim bersih " + ip.Teks + """ + txt.Teks + """), 0);//kirim pesan

Prosedur ini memeriksa apakah semua kolom wajib diisi. Jika tidak ada teks pesan, setel tanda "!"; jika alamat IP tidak ditentukan, maka kami mengirim pesan ke komputer lokal dengan alamat 127.0.0.1; jika jumlah pesan tidak ditentukan, maka kami mengirim satu pesan. Pesan dikirim menggunakan perintah net send standar, yang memiliki sintaks berikut:

net kirim pesan alamat ip.

Sekarang mari kita tangani event OnTimer:

jam: HWND;//menyimpan ID jendela
jika tidak aman. Diperiksa kemudian//jika kotak centang tidak dicentang
Timer1.Enabled:= Salah;//nonaktifkan pemantauan
jika aman. Diperiksa kemudian//jika kotak centang dicentang
//mencari jendela pesan
h:= FindWindow(nil, "Layanan Pesan");//menutup semua jendela yang ditemukan
jika h<>

Jika kotak centang Nonaktifkan penerimaan pesan dipilih, maka kami mulai memantau jendela yang judulnya menunjukkan bahwa ini adalah pesan, dan menutup semua jendela yang ditemukan. Jika kotak centang tidak dicentang, pemantauan dinonaktifkan.

Agar dapat beralih di antara dua mode ini, Anda perlu membuat event handler secure.OnClick:

jika aman. Diperiksa kemudian//jika kotak centang dicentang...
Timer1.Enabled:= Benar;//...aktifkan pemantauan

Saat tombol ditekan Mengirim kami hanya akan memanggil prosedur bom:

Untuk membuat hidup lebih mudah bagi pengguna, kami akan memastikan bahwa pesan juga terkirim dengan menekan sebuah tombol di bidang input teks apa pun. Untuk melakukan ini, Anda perlu membuat event handler OnKeyPress untuk setiap bidang. Kode untuk pengendali ini adalah untuk bidang ip, yang kemudian dapat ditetapkan ke bidang txt dan caranya:

jika kunci= #13 lalu//jika ada tombol yang ditekan
bom;//kirim pesan

Kode sumber modul lengkap

Kode lengkap modul program untuk mengirim pesan melalui jaringan lokal disajikan pada Listing 15.1.

Daftar 15.1. Modul program untuk mengirim pesan melalui jaringan lokal

Windows, Pesan, SysUtils, Varian, Kelas, Grafik, Kontrol, Formulir, Dialog, StdCtrls, ExtCtrls;

procedure Timer1Timer(Pengirim: TObject);
prosedur secureClick(Pengirim: TObject);
procedure ipKeyPress(Pengirim: TObject; Kunci var: Char);
prosedur txtKeyPress(Pengirim: TObject; var Kunci: Char);
prosedur howKeyPress(Pengirim: TObject; var Kunci: Char);
prosedur Button1Click(Pengirim: TObject);


//periksa apakah pesan teksnya kosong
jika txt.Teks = "" maka txt.Teks:= "!";
//jika kuantitas tidak ditentukan, maka kami mengirimkan satu pesan
jika bagaimana.Teks= "" lalu bagaimana.Teks:= "1";
jika ip.Teks = "" maka ip.Teks:= "127.0.0.1"; (jika alamat IP tidak ditentukan, maka kami mengirimkannya ke komputer lokal)
//mengirimkan sejumlah pesan yang ditentukan
untuk i:=1 hingga StrToInt(how.Text) lakukan
WinExec(PChar("kirim bersih " + ip.Teks + """ + txt.Teks + """), 0); //kirim pesan

prosedur TForm1.Timer1Timer(Pengirim: TObject);
jam: HWND; //menyimpan ID jendela
jika tidak aman. Dicentang maka //jika kotak centang tidak dicentang
Timer1.Enabled:= Salah; //nonaktifkan pemantauan
jika aman. Dicentang maka //jika kotak centang dicentang
//mencari jendela pesan
h:= FindWindow(nil, "Layanan Pesan"); //menutup semua jendela yang ditemukan
jika h<>0 lalu PostMessage(h, WM_QUIT, 0, 0);

prosedur TForm1.secureClick(Pengirim: TObject);
jika aman. Dicentang maka //jika kotak centang dicentang...
Timer1.Enabled:= Benar; //...aktifkan pemantauan

procedure TForm1.ipKeyPress(Pengirim: TObject; Kunci var: Char);
jika kunci = #13 maka //jika tombol ditekan
bom; //kirim pesan

prosedur TForm1.Button1Click(Pengirim: TObject);

⊚ Semua file proyek dan file executable dari program yang dibahas terdapat pada CD yang disertakan dengan buku di folder Bab 15.

Seringkali, program Delphi menggunakan email. Artikel ini akan menjelaskan sepenuhnya cara mengirim email Anda ke pengguna lain. menggunakan delphi. Dalam hal ini, kita hanya akan menggunakan komponen Delphi standar.

Pertama, mari kita buat proyek baru dan beri nama \"Mengirim email menggunakan delphi\". Kemudian Anda perlu mentransfer beberapa komponen ke form: 1x Memo, 3x Edit, 2x Botton, dan Anda juga perlu mentransfer IdSMTP, IdAntiFreeze, IdMessage. Selanjutnya, pada acara onclick tombol apa pun kita menulis:

//memilih server SMTP. DI DALAM saat ini biaya yandex. IdSMTP1.Host:= "smtp.yandex.ru"; //login Anda (untuk beberapa, Anda perlu menulis dengan domain). IdSMTP1.Nama Pengguna:= " [dilindungi email]"; //kata sandi email. IdSMTP1.Password:= "qwerty123"; //port, sebaiknya gunakan 587. IdSMTP1.Port:=587; //Edit2 akan menyertakan subjek surat. IdMessage1.Subject:= Edit2. Teks; //Edit1 akan berisi alamat penerima IdMessage1.Recipients.EMAilAddresses:= Edit1.Text; //email asal pengirimannya. [dilindungi email]"; // di memo1 akan ada teks yang ingin Anda kirim. IdMessage1.Body.Text:= memo1.Text ; // di Edit3 akan ada tanda tangan elektronik(Nama). IdMessage1.From.Name:= Edit3.Teks; //sambungkan IdSMTP1.sambungkan; //kirim IdSMTP1.Kirim(IdMessage1); //putuskan sambungan IdSMTP1.Putuskan sambungan;

Jika IdMessage menampilkan tanda tanya

Bug ini disebabkan oleh fakta bahwa Anda memasukkan huruf Rusia, dan komponen memo tidak dapat membacanya dengan benar; untuk ini Anda perlu menentukan pengkodean Utf8.

// atur pengkodean IdMessage1.Charset:="UTF-8"; // terjemahkan teks ke dalam pengkodean yang diperlukan IdMessage1.Body.Text:=UTF8Encode(memo1.text);

suatu tempat seperti ini

IdTCPClient1.Host:= "127.0.0.1"; IdTCPClient1.Connect;// IdTCPClient1.Socket.WriteLn("command"); // mengirim perintah perintah dan umpan baris // Tunggu respons dan tutup koneksi txtResults.Lines.Append(IdTCPClient1.Socket.ReadLn); IdTCPClient1.Putuskan sambungan;

dalam hal ini, perintahnya hanyalah teks dengan umpan baris. Hal ini membuatnya lebih mudah untuk menerima perintah dari sisi lain (hanya ReadLn). Secara umum, Anda perlu membuat (atau menggunakan protokol yang sudah jadi).

di atasnya adalah klien. Dan sekarang servernya. Dengan server, segalanya menjadi sedikit lebih rumit. Jelas bahwa normal jika sebuah server melayani tidak hanya satu klien, tetapi banyak klien. Dan ada beberapa “skema” untuk ini.

    Klasik - satu klien - satu utas. Skema ini mudah dikodekan dan intuitif. Ini diparalelkan dengan baik antar inti. Kerugiannya adalah biasanya sangat sulit membuat banyak thread, dan ini membatasi jumlah klien. Untuk program 32-bit, batas atasnya adalah sekitar 1500 (satu setengah ribu) thread per proses. Namun dalam kasus ini, biaya overhead untuk peralihannya dapat “memakan” seluruh persentasenya. Ini adalah skema yang digunakan di indy.

    Klasik kedua adalah semua klien di satu thread. Skema ini seringkali lebih kompleks untuk dikodekan, namun dengan pendekatan yang tepat, skema ini memungkinkan Anda mempertahankan 20-30 ribu “pengguna lambat” tanpa beban pada kernel. Keuntungan kuat dari skema ini adalah Anda dapat melakukannya tanpa mutex dan primitif sinkronisasi lainnya. Skema ini digunakan oleh NodeJS dan kelas standar untuk bekerja dengan jaringan di Qt.

    Campur aduk. Dalam hal ini, beberapa thread dibuat, yang masing-masing melayani sejumlah klien tertentu. Yang paling sulit untuk dikodekan, tetapi memungkinkan Anda memanfaatkan sumber daya perangkat keras secara maksimal.

Bagaimana hal itu dilakukan di Indy. Server Indy tcp membuat thread terpisah (TThread) untuk setiap koneksi dan pekerjaan lebih lanjut dengan klien berjalan di dalamnya. Indy menyembunyikan ini dengan baik, membiarkan pengguna hanya mengimplementasikan metode IdTCPServer.onExecute. Namun, seperti yang saya katakan di atas, metode ini diluncurkan di thread terpisah dan bersifat pribadi untuk setiap klien. Artinya sebagai berikut:

  • dalam metode ini Anda dapat memanggil sleep dan hanya satu klien yang akan menunggu. Semua yang lain akan berfungsi (tetapi jika Anda memanggil sleep di pengendali klik tombol, maka hasilnya diketahui)
    • Lebih baik mengakses variabel global hanya melalui sinkronisasi primitif.
    • Anda perlu mengakses elemen gui dengan hati-hati dan benar. Lebih baik tidak melakukannya secara langsung (beberapa komponen mengizinkan akses ke komponen tersebut dari thread lain, tetapi Anda perlu membaca dokumen dengan cermat).
    • Anda perlu mengakses klien lain melalui pemblokiran (karena jika dua utas ingin menulis ke pengguna yang sama, tidak ada hasil yang baik).

Mari kita lihat contoh yang sangat sederhana. Kami menanggapi setiap permintaan klien dengan cara yang sama dan menutup koneksi (semacam server gema).

Prosedur TForm1.IdTCPServer1Execute(AContext: TIdContext); var strTeks: String; mulai //Menerima string dari klien strText:= AContext.Connection.Socket.ReadLn;

//Tanggapi AContext.Connection.Socket.WriteLn(strText); //Tutup koneksi dengan pengguna AContext.Connection.Disconnect; akhir; AContext adalah objek khusus yang berisi semua

informasi yang diperlukan

tentang klien. IdTcpServer sendiri berisi daftar konteks ini dan dapat diakses. Mari kita pertimbangkan siaran yang lebih kompleks. Artinya, kirimkan satu pesan ke semua orang

Klien Var: TList;

saya: bilangan bulat; mulai // bukti bodoh :) jika tidak Ditugaskan (IdTCPServer1.Contexts) lalu keluar; // ambil daftar klien dan kunci Klien:=IdTCPServer1.Contexts.LockList; penggunaan akan menjadi yang berikutnya. Ketika klien baru saja terhubung, kolom ini kosong. Ketika lolos pemeriksaan nama-kata sandi, kita membuat objek (milik kita), menyimpan nama di sana dan menuliskannya di properti Data. Dan kemudian, ketika Anda perlu melakukan loop melalui klien yang terhubung, kami cukup membacanya. Tentu saja, jika ada ribuan pengguna, akan mahal untuk melihat semua pengguna setiap saat. Namun bagaimana melakukan hal ini dengan lebih optimal adalah topik artikel besar lainnya.