“Saya ingin layanan yang tinggal di memori dan UI pengaturan saling menukar perintah.” “Saya ingin mengisolasi hanya pekerjaan yang membutuhkan hak administrator ke proses terpisah.” “Saya ingin alat di PC yang sama saling mengirim data.” — Ketika komunikasi antarpproses (IPC) semacam ini menjadi perlu di Windows, standar yang harus Anda pertimbangkan lebih dulu adalah named pipe.
Artikel tentang memilih komunikasi antarpproses Windows menempatkan named pipe sebagai “kandidat pertama untuk IPC di mesin yang sama”. Artikel ini adalah pembahasan rincinya. Mengapa mereka kandidat pertama, bagaimana Anda memilih mode dan bentuk server, dan apa yang harus dilindungi ketika layanan berhak istimewa memakainya — ditujukan kepada pengembang yang menulis aplikasi bisnis dan layanan di Windows, artikel ini menata bahan untuk penilaian desain itu dari sumber primer.
1. Kesimpulan lebih dulu
- Named pipe adalah saluran antarpproses dua arah dengan ruang nama berbentuk
\\.\pipe\name. Anda dapat membuat beberapa instans dengan nama yang sama dan menerima beberapa klien sekaligus.1 - Alasan mereka kandidat pertama untuk IPC di mesin yang sama adalah model keamanannya. Anda dapat mengendalikan siapa yang terhubung dengan ACL, dan server dapat memeriksa serta meminjam (meng-impersonate) akun Windows klien. TCP localhost tidak punya keduanya.2
- Jika Anda ingin memperlakukan “satu penulisan = satu pesan”, pakai mode pesan; jika Anda sudah punya framing sendiri, pakai mode byte. Bahkan dalam mode pesan Anda tetap perlu menangani pembacaan terbelah pada buffer yang terlalu pendek (ERROR_MORE_DATA).3
- Tangani beberapa klien dengan “beberapa instans + overlapped I/O” atau dengan “.NET async/await”. Sampel resmi menunjukkan bentuk yang memproses beberapa instans pada satu thread.4
- Minimum keamanan adalah empat poin: tolak jarak jauh (PIPE_REJECT_REMOTE_CLIENTS), buat ACL eksplisit, deteksi pembajakan dengan FILE_FLAG_FIRST_PIPE_INSTANCE, dan minimalkan tingkat impersonation di sisi klien.56
- Untuk
ImpersonateNamedPipeClient, memeriksa nilai kembalian adalah nyawa. Abaikan kegagalan dan pemrosesan lanjut dengan hak server.6
2. Apa itu named pipe — ruang nama, instans, dan cara koneksi bekerja
Named pipe adalah saluran yang dikenali oleh nama seperti \\.\pipe\MyCompany.MyApp.Control. Server membuatnya dengan CreateNamedPipe, dan klien membuka nama yang sama dengan CreateFile. Setelah terbuka, kedua sisi membaca dan menulis dengan ReadFile / WriteFile — poin khasnya adalah Anda dapat memakainya dalam bentuk yang sama seperti I/O berkas.1
Konsep penting adalah instans. Anda dapat membuat beberapa instans pipe dengan nama yang sama, dan satu instans adalah satu saluran dengan satu klien. Panggilan CreateNamedPipe pertama menentukan jumlah instans maksimum (atau tanpa batas).3
Koneksi di sisi klien punya resep standar. Ketika setiap instans sedang dipakai, CreateFile gagal dengan ERROR_PIPE_BUSY, jadi Anda menunggu yang kosong dengan WaitNamedPipe lalu mencoba lagi. Selain itu, akses yang Anda tentukan saat membuka harus cocok dengan arah yang server buat — pipe dua arah dapat dibuka dengan baca atau tulis, tetapi pipe outbound yang hanya ditulis server harus dibuka hanya-baca, dan pipe inbound yang hanya dibaca server harus dibuka hanya-tulis, atau CreateFile gagal.7
flowchart TB
accTitle: Arah pipe dan spesifikasi akses klien
accDescr: Klien dapat membuka pipe dua arah dengan baca atau tulis, tetapi harus membuka pipe outbound yang hanya ditulis server sebagai hanya-baca, dan pipe inbound yang hanya dibaca server sebagai hanya-tulis
q{"Arah yang server buat?"} -->|"Dua arah"| dc["Baca atau tulis OK"]
q -->|"Outbound"| oc["Buka hanya-baca"]
q -->|"Inbound"| ic["Buka hanya-tulis"]
Gambar 1: Ketidakcocokan antara arah dan spesifikasi akses menjadi kegagalan CreateFile. Saat menyelidiki kesalahan koneksi, periksa di sini lebih dulu.
flowchart TB
accTitle: Struktur dasar named pipe
accDescr: Server membuat beberapa instans pipe dengan nama yang sama dan menunggu koneksi dengan ConnectNamedPipe; setiap klien membuka nama itu dengan CreateFile dan punya saluran dua arah satu-ke-satu dengan satu instans
s["Server"] --> i1["Instans 1"]
s --> i2["Instans 2"]
s --> i3["Instans 3"]
c1["Klien A"] <--> i1
c2["Klien B"] <--> i2
c3["Klien C"] <--> i3
Gambar 2: Dengan menahan beberapa instans nama yang sama, satu server dapat berbicara satu-ke-satu dengan beberapa klien pada saat yang sama.
Named pipe juga dapat dibuka dari jarak jauh lewat SMB (\\server\pipe\name), tetapi dalam desain modern hampir tidak ada alasan untuk memakainya secara aktif; persoalannya justru tidak membiarkannya terbuka ketika Anda tidak memakainya (Bab 5).
3. Mode byte dan mode pesan
Sebuah pipe punya dua mode transfer.3
- Mode byte (PIPE_TYPE_BYTE): “aliran byte yang tak terputus” seperti TCP. Anda sendiri yang memutuskan di mana satu pesan berakhir (Anda merancang framing seperti prefix panjang).
- Mode pesan (PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE): satu penulisan diperlakukan sebagai satu pesan, dan pembaca menerimanya dalam satuan itu. Ini lebih mudah untuk pertukaran permintaan/respons.
Mode pesan juga punya pendamping yang nyaman, TransactNamedPipe, yang mengirim permintaan dan menerima respons dalam satu panggilan.8 Ada jebakannya, walaupun. Jika buffer terima lebih kecil dari seluruh pesan, pembacaan mengembalikan ERROR_MORE_DATA dan menjadi pembacaan terbelah. Jangan berasumsi bahwa mode pesan berarti “satu Read selalu membawa semuanya”; Anda tetap perlu menulis loop yang membaca sisanya. Perhatikan bahwa mode baca adalah pengaturan per-handle, dan CreateNamedPipe menentukannya hanya di sisi server. Klien menentukannya dengan SetNamedPipeHandleState setelah CreateFile (di .NET, ReadMode setelah terhubung).7
flowchart TB
accTitle: Loop pembacaan terbelah di mode pesan
accDescr: Jika ReadFile berhasil pesan lengkap; jika mengembalikan ERROR_MORE_DATA Anda membaca sisa yang tidak muat di buffer dan menggabungkannya; kesalahan lain diperlakukan sebagai putus koneksi
read["Baca dengan ReadFile"] --> r{"Hasil?"}
r -->|"Berhasil"| done["Pesan lengkap"]
r -->|"ERROR_MORE_DATA"| more["Baca sisa dan gabungkan"]
more --> read
r -->|"Kesalahan lain"| dis["Perlakukan sebagai putus"]
Gambar 3: Bahkan dalam mode pesan Anda perlu “loop baca-sisanya”; tanpa itu, hanya pesan besar yang rusak.
flowchart TB
accTitle: Perbedaan mode byte dan mode pesan
accDescr: Di mode byte tiga penulisan menjadi aliran byte tak terputus dan penerima harus membelahnya; di mode pesan satuan setiap penulisan dipertahankan dan sampai ke penerima apa adanya
bw["Mode byte: tulis AAA, BB, CCCC"] --> br["Diterima sebagai aliran AAABBCCCC"]
br --> bf["Anda merancang framing sendiri"]
mw["Mode pesan: tiga tulis yang sama"] --> mr["Diterima sebagai tiga pesan: AAA, BB, CCCC"]
mr --> mf["Satuan penulisan dipertahankan"]
Gambar 4: Mode pesan mempertahankan “satuan sebuah penulisan” dan mengirimkannya. Desain framing menjadi tidak perlu; jangan lupa menangani pembacaan terbelah.
Aturan praktis untuk memilihnya sederhana. Jika pertukarannya berbentuk “permintaan dan respons”, mode pesan. Jika Anda membawa bentuk yang sudah punya framing (data terserialisasi berprefix panjang atau transfer aliran), pakai mode byte. Di .NET, menentukan PipeTransmissionMode.Message sesuai dengan yang pertama.9
4. Desain server — satu thread per klien, atau overlapped?
Operasi dasar server adalah loop “buat instans → tunggu klien dengan ConnectNamedPipe → baca dan tulis → putuskan dan ke klien berikutnya”. Ada dua bentuk untuk berbicara dengan beberapa klien sekaligus.
Sinkron, satu thread per instans. Anda menugaskan satu thread ke setiap instans, dan masing-masing berbicara dengan kliennya sendiri lewat I/O sinkron. Kodenya lugas, tetapi Anda mengonsumsi satu thread per klien, dan Anda juga perlu cara untuk keluar dari I/O yang memblokir saat mematikan semuanya.
Overlapped (asinkron). Anda membuat instans dengan FILE_FLAG_OVERLAPPED, mengeluarkan ConnectNamedPipe / ReadFile / WriteFile secara asinkron, dan membiarkan sejumlah kecil thread menangani penyelesaian untuk setiap instans. Sampel resmi Microsoft menunjukkan server yang menunggu pada larik event dengan WaitForMultipleObjects dan memproses beberapa instans pada satu thread.4 Uraian umum I/O asinkron seperti yang dijelaskan di artikel seri I/O, dan pada skala lebih besar Anda juga dapat menempelkan IOCP atau I/O thread pool.
flowchart TB
accTitle: Struktur server overlapped
accDescr: Penyelesaian operasi asinkron setiap instans diterima pada larik event, dan sejumlah kecil thread menunggu dengan WaitForMultipleObjects lalu memajukan instans yang selesai, memisahkan jumlah thread dari jumlah klien
i1["Operasi async instans 1"] --> ev["Larik event"]
i2["Operasi async instans 2"] --> ev
i3["Operasi async instans 3"] --> ev
ev --> wait["Tunggu selesai dengan WaitForMultipleObjects"]
wait --> proc["Majukan instans yang selesai"]
proc --> wait
Gambar 5: Bentuk overlapped memisahkan jumlah thread dari jumlah klien. Sampel resmi memutar siklus ini pada satu thread.
.NET hampir menghilangkan pilihan ini. Memakai WaitForConnectionAsync / ReadAsync / WriteAsync milik NamedPipeServerStream bersama async/await, Anda mendapat efisiensi overlapped dalam kode yang sama lugasnya dengan bentuk sinkron.9
// C#: skeleton of a server that accepts multiple clients
while (!token.IsCancellationRequested)
{
var server = new NamedPipeServerStream(
"MyCompany.MyApp.Control",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);
try
{
await server.WaitForConnectionAsync(token);
}
catch
{
await server.DisposeAsync(); // dispose yourself when leaving before a connection
throw;
}
_ = HandleClientAsync(server, token); // ownership after connect goes to the handler
}
PipeOptions.CurrentUserOnly adalah spesifikasi yang “mengizinkan koneksi hanya dari proses pengguna yang sama”, default yang nyaman dan aman yang menghemat Anda menulis ACL sendiri.10 Itu tidak dapat dipakai dalam penyiapan yang menyeberangi pengguna (layanan ↔ aplikasi di sesi pengguna, dan sejenisnya), jadi dalam kasus itu Anda beralih ke desain ACL di bab berikutnya.
flowchart TB
accTitle: Loop terima server asinkron .NET
accDescr: Loop terima membuat NamedPipeServerStream, menunggu koneksi dengan WaitForConnectionAsync, dan saat tiba melepaskan penanganan klien secara asinkron lalu segera kembali ke terima berikutnya, sehingga koneksi bersamaan ditangani dalam kode yang lugas
mk["Buat stream server"] --> wc["Tunggu dengan WaitForConnectionAsync"]
wc --> got["Koneksi tiba"]
got --> hd["Lepas penanganan klien secara async"]
hd --> mk
Gambar 6: Loop terima berpegang pada siklus “tunggu → lepas → berikutnya”, dan pemrosesan setiap klien berjalan paralel.
5. Keamanan — empat keharusan ketika layanan berhak istimewa memakai pipe
Alasan terbesar named pipe menjadi kandidat pertama untuk IPC di mesin yang sama adalah model keamanannya, tetapi itu hanya jika Anda mengonfigurasinya dengan benar. Terutama dalam desain broker “layanan berhak administrator + aplikasi UI berhak rendah”, pipe adalah batas hak itu sendiri. Ada empat poin yang harus dipatok.
(1) Tolak jarak jauh. Pipe yang Anda maksudkan sebagai IPC lokal bisa dibuka dari jaringan sudah, dengan sendirinya, permukaan serangan. Tentukan PIPE_REJECT_REMOTE_CLIENTS pada CreateNamedPipe dan koneksi klien jarak jauh ditolak secara otomatis.5
(2) Buat ACL eksplisit. Teruskan security descriptor di SECURITY_ATTRIBUTES dan persempit pengguna serta grup yang diizinkan terhubung. Jangan beri klien GENERIC_WRITE — hak FILE_CREATE_PIPE_INSTANCE yang termasuk di dalamnya akan membiarkan klien yang berwenang sendiri membuat instans server dengan nama yang sama dan mencuri koneksi berikutnya. Berikan baca dan tulis sebagai hak terpisah, dan jangan teruskan hak pembuatan instans.11
(3) Cegah pembajakan nama. Nama pipe bersifat siapa cepat dia dapat. Jika proses jahat membuat pipe dengan nama yang sama lebih dulu dan menunggu, klien terhubung ke server palsu. Server menentukan FILE_FLAG_FIRST_PIPE_INSTANCE saat membuat instans pertama, menjamin bahwa “saya yang pertama”, dan jika itu gagal ia mencurigai pembajakan dan berhenti. Flag ini hanya untuk instans pertama yang mengklaim nama; memasangnya pada instans kedua dan seterusnya membuat pembuatan gagal.3
| (4) Klien meminimalkan tingkat impersonation ke yang dibutuhkan. Ini persiapan untuk kasus rekan adalah server palsu. Jika klien menentukan **SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION** pada CreateFile, server dapat mengidentifikasi klien tetapi tidak dapat meminjam hak itu dan bertindak.2 Ini adalah trade-off terhadap alur impersonation, walaupun — dalam desain broker di mana server melakukan akses sungguhan di bawah hak klien, tingkat identification tidak cukup agar impersonation berhasil, dan Anda perlu mengizinkan SECURITY_IMPERSONATION. Izin itu bersyarat pada yakin Anda terhubung ke server asli. Anti-pembajakan di sisi server hanyalah mekanisme yang menyadari lewat start yang gagal; jika layanan asli absen dan penyerang membuat pipe nama yang sama lebih dulu, klien tetap dapat terhubung ke server palsu. Izinkan hanya ketika Anda dapat mengonfirmasi rekan lewat start layanan yang terjamin atau autentikasi bersama setelah terhubung. |
Pemeriksaan identitas dan peminjaman hak di sisi server adalah ImpersonateNamedPipeClient. Panggil ini setelah membaca permintaan dari pipe dan thread pemanggil mulai berjalan dalam konteks keamanan pengirim pesan terakhir yang dibaca. Buka berkas dengan hak klien dan pemeriksaan akses dilakukan terhadap klien — mekanisme yang membuat layanan berhak istimewa mengeksekusi “operasi yang diminta, dengan hak peminta”.6 Syarat mutlak memakainya adalah memeriksa nilai kembalian. Lanjut setelah impersonation gagal dan operasi berikutnya berjalan dengan hak tinggi server sendiri. Dokumentasi resmi menyatakan secara eksplisit bahwa “saat gagal Anda tidak boleh mengeksekusi permintaan klien”. Bersama RevertToSelf setelah pekerjaan, praktik di artikel tentang token impersonation berlaku apa adanya.
sequenceDiagram
accTitle: Alur penanganan permintaan yang memakai impersonation
accDescr: Server membaca permintaan dari pipe, memastikan ImpersonateNamedPipeClient berhasil, lalu melakukan operasi dengan hak klien dan kembali ke konteks sendiri dengan RevertToSelf. Jika impersonation gagal ia menolak permintaan tanpa mengeksekusinya
participant C as Klien
participant S as Server
C->>S: Kirim permintaan
S->>S: Baca permintaan
S->>S: ImpersonateNamedPipeClient
Note over S: Saat gagal, tolak tanpa mengeksekusi
S->>S: Lakukan operasi dengan hak klien
S->>S: RevertToSelf untuk pulihkan konteks
S->>C: Balas dengan hasil
Gambar 7: Memastikan impersonation berhasil dan RevertToSelf yang andal datang sebagai satu paket. Lanjut saat gagal dan itu berjalan dengan hak server.
flowchart TB
accTitle: Empat poin yang melindungi pipe layanan berhak istimewa
accDescr: Sisi server mengeraskan pintu masuk dengan penolakan jarak jauh, ACL eksplisit, dan jaminan instans pertama; sisi klien menentukan tingkat impersonation minimum yang dibutuhkan agar server palsu tidak dapat meminjam hak (persempit ke tingkat identification jika desain tidak membiarkan server meminjam hak)
subgraph sv["Sisi server"]
r1["PIPE_REJECT_REMOTE_CLIENTS"]
r2["Batasi penghubung dengan ACL"]
r3["FIRST_PIPE_INSTANCE (instans pertama saja)"]
end
subgraph cl["Sisi klien"]
r4["Tentukan tingkat impersonation minimum"]
end
sv --> safe["Pipe sebagai batas hak"]
cl --> safe
Gambar 8: Dalam desain di mana pipe adalah batas hak, terapkan tiga poin sisi server plus satu poin sisi klien sebagai satu set.
6. Jebakan praktis
Balapan urutan start. Jika klien datang terhubung sebelum server membuat pipe, Anda mendapat kesalahan “pipe tidak ada”. Sisi klien membangun “tidak ada → tunggu sebentar dan coba lagi”. Sebaliknya, prinsip di sisi server adalah mulai mendengarkan dengan ConnectNamedPipe sebelum klien start.8
flowchart TB
accTitle: Alur coba ulang koneksi klien
accDescr: Buka pipe dengan CreateFile; jika pipe tidak ada tunggu sebentar dan coba lagi; jika setiap instans dipakai (ERROR_PIPE_BUSY) tunggu yang kosong dengan WaitNamedPipe lalu coba lagi; saat berhasil masuk komunikasi
cf["Buka dengan CreateFile"] --> ok{"Hasil?"}
ok -->|"Berhasil"| go["Mulai berkomunikasi"]
ok -->|"Pipe tidak ada"| wait1["Tunggu (server belum start)"]
ok -->|"ERROR_PIPE_BUSY"| wnp["WaitNamedPipe (instans kosong)"]
wait1 --> cf
wnp --> cf
Gambar 9: Penanganan koneksi klien membedakan dua jenis kegagalan, “tidak ada” dan “penuh”, dan keduanya kembali ke coba ulang.
Mendeteksi putus koneksi. Ketika rekan keluar, Read/Write gagal dengan ERROR_BROKEN_PIPE dan sejenisnya. Itu bukan anomali; itu komunikasi sehari-hari. Server mendeteksi putus, DisconnectNamedPipe instans, dan bersiap untuk koneksi berikutnya; klien terhubung kembali — gagasan “rekoneksi idempoten” yang dijelaskan di artikel tentang tidur/bangun berlaku di sini juga.
Asumsi tentang ukuran pesan. Di atas pembacaan terbelah mode pesan (Bab 3), jika Anda tidak memutuskan sebagai bagian dari protokol “berapa byte maksimum satu pesan”, rekan yang jahat (atau cacat) dapat memboroskan memori Anda dengan pesan raksasa. Tetapkan batas atas, dan putuskan jika terlampaui; itu pendekatan yang aman.
Penyelesaian tulis dan penerimaan rekan adalah hal yang berbeda. Keberhasilan WriteFile tidak berarti aplikasi rekan telah memproses data. Operasi yang membutuhkan kepastian ditanggung oleh desain seperti mengonfirmasi dengan pesan respons, dan memasukkan korespondensi permintaan dan respons ke dalam protokol.
7. Ringkasan
- Named pipe adalah kandidat pertama untuk IPC di mesin yang sama. Alasannya adalah kemudahan yang sama seperti I/O berkas, dan integrasi dengan model keamanan Windows berupa ACL dan impersonation.
- Pilihan mode adalah “mode pesan untuk permintaan dan respons, mode byte jika Anda sudah punya framing sendiri”. Bahkan dalam mode pesan Anda tetap perlu menangani pembacaan terbelah (ERROR_MORE_DATA).
- Beberapa klien adalah beberapa instans + overlapped, atau .NET async/await. Untuk pekerjaan baru, bentuk asinkron .NET adalah yang paling lugas.
- Pada pipe yang menjadi batas hak, ambil penolakan jarak jauh, ACL eksplisit, FIRST_PIPE_INSTANCE (instans pertama saja), dan meminimalkan tingkat impersonation sisi klien sebagai satu set.
- Untuk
ImpersonateNamedPipeClient, memeriksa nilai kembalian danRevertToSelfadalah nyawa. - Rajut “keseharian komunikasi” — urutan start, putus koneksi, batas atas pesan, konfirmasi respons — ke dalam desain protokol.
Named pipe adalah API lama, tetapi untuk penggunaan “membuat proses saling berbicara di mesin yang sama sambil menghormati batas akun Windows”, mereka tetap alat yang paling alami untuk pekerjaan itu. Titik penilaian desain hampir habis dalam lingkup artikel ini. Setelah itu, tuliskan protokol Anda sendiri di selembar kertas sebelum mulai mengimplementasikan.
Artikel terkait
- Memilih komunikasi antarpproses Windows ── Tabel keputusan untuk named pipe / TCP / gRPC / memori bersama / COM
- Cara mengisolasi secara konkret “hanya operasi yang membutuhkan hak administrator” di aplikasi Windows
- Menangani token impersonation Windows dengan benar — meminjam hak per thread dan kembali dengan aman
- Kedalaman I/O Windows (Bagian 2) — I/O sinkron dan asinkron: arti sesungguhnya OVERLAPPED
- Jebakan memori bersama dan praktik terbaik praktis
Area konsultasi terkait
KomuraSoft LLC menangani desain dan implementasi yang melibatkan komunikasi antarpproses — memisahkan layanan dari aplikasi UI, mengisolasi hak administrator, dan sejenisnya — mengganti IPC yang ada (memori bersama, soket buatan sendiri, COM, dan sebagainya) dengan named pipe, serta tinjauan keamanan komunikasi pipe layanan berhak istimewa. Konsultasi yang dimulai dari menguji desain protokol bersama kami dipersilakan.
- Pengembangan aplikasi Windows
- Konsultasi teknis dan tinjauan desain
- Investigasi bug dan akar masalah
- Hubungi kami
Tautan referensi
-
Microsoft Learn, Named Pipes. Tentang named pipe sebagai saluran satu arah atau dua arah antara pipe server dan satu atau lebih pipe client; tentang setiap instans berbagi nama yang sama sambil punya buffer dan handle independen; dan tentang dapat dipakai dari proses lokal maupun jarak jauh. ↩ ↩2
-
Microsoft Learn, Impersonating a Named Pipe Client. Tentang impersonation yang membiarkan thread server beroperasi dalam hak klien; tentang tingkat impersonation bawaan SecurityImpersonation; dan tentang klien yang dapat mengendalikan tingkat impersonation dengan flag SECURITY_SQOS_PRESENT pada saat CreateFile (SECURITY_IDENTIFICATION hanya mengizinkan identifikasi). ↩ ↩2
-
Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h). Tentang arah pipe (inbound, outbound, dua arah), tipe byte dan tipe pesan (PIPE_TYPE_BYTE / PIPE_TYPE_MESSAGE) serta mode baca (PIPE_READMODE_MESSAGE), jumlah instans maksimum (PIPE_UNLIMITED_INSTANCES), mode asinkron lewat FILE_FLAG_OVERLAPPED, jaminan instans pertama lewat FILE_FLAG_FIRST_PIPE_INSTANCE, dan timeout bawaan WaitNamedPipe. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Named Pipe Server Using Overlapped I/O. Tentang sampel resmi server satu thread yang memproses koneksi simultan dengan beberapa klien lewat operasi overlapped. Tentang bentuk yang menunggu pada struktur OVERLAPPED dan event setiap instans dengan WaitForMultipleObjects dan memajukan mesin keadaan instans yang selesai, serta mengonfirmasi penyelesaian I/O tertunda dengan GetOverlappedResult. ↩ ↩2
-
Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h). Tentang dua mode klien jarak jauh, PIPE_ACCEPT_REMOTE_CLIENTS (terima koneksi jarak jauh dan periksa terhadap security descriptor) dan PIPE_REJECT_REMOTE_CLIENTS (tolak otomatis koneksi klien jarak jauh). ↩ ↩2
-
Microsoft Learn, ImpersonateNamedPipeClient function (namedpipeapi.h). Tentang thread sisi server yang mulai impersonation dalam konteks keamanan klien dari pesan terakhir yang dibaca dari pipe; tentang kembali dengan RevertToSelf setelah selesai; dan tentang lanjut setelah impersonation gagal yang menyebabkan eksekusi dalam konteks (berhak istimewa) proses server sendiri, sehingga nilai kembalian harus selalu diperiksa dan saat gagal permintaan klien tidak boleh dieksekusi. ↩ ↩2 ↩3
-
Microsoft Learn, Named Pipe Client. Tentang klien yang membuka pipe dengan CreateFile; tentang ERROR_PIPE_BUSY ketika setiap instans dipakai, menunggu yang kosong dengan WaitNamedPipe; dan tentang handle yang dibuka secara bawaan byte-read, blocking, dan non-overlapped, dengan SetNamedPipeHandleState dapat mengubahnya ke mode baca pesan. ↩ ↩2
-
Microsoft Learn, Named Pipe Operations. Tentang operasi overlapped lewat ReadFileEx / WriteFileEx, pembacaan tanpa mengonsumsi lewat PeekNamedPipe, TransactNamedPipe yang melakukan kirim permintaan dan terima respons dalam satu panggilan pada pipe dua arah tipe pesan, dan pembacaan yang memblokir sebelum klien start yang dapat menyebabkan balapan. ↩ ↩2
-
Microsoft Learn, How to: Use Named Pipes for Network Interprocess Communication (.NET). Tentang menghubungkan serta membaca/menulis dengan NamedPipeServerStream / NamedPipeClientStream, transfer satuan pesan lewat PipeTransmissionMode.Message, dan menangani beberapa klien dengan metode asinkron. ↩ ↩2
-
Microsoft Learn, PipeOptions Enum (System.IO.Pipes). Tentang mengaktifkan I/O asinkron dengan Asynchronous, dan tentang CurrentUserOnly yang dapat mengizinkan koneksi hanya dengan proses pengguna yang sama (dan tingkat elevasi yang sama). ↩
-
Microsoft Learn, Named Pipe Security and Access Rights. Tentang komposisi hak akses named pipe; tentang GENERIC_WRITE yang mencakup FILE_CREATE_PIPE_INSTANCE, sehingga memberi klien generic write juga mengizinkan membuat instans server; dan tentang baca serta tulis data yang diberikan sebagai hak akses terpisah. ↩
Artikel terkait
Artikel terbaru dengan tag yang sama untuk mendalami topik-topik terdekat.
Win32 Thread Pool API — konkurensi tanpa membuat thread, lewat CreateThreadpoolWork
Apakah Anda menebar panggilan CreateThread di seluruh kode native? Artikel ini menjelaskan Win32 thread pool API yang didesain ulang di V...
Kedalaman virtualisasi Windows (Bagian 2) — Memori yang bahkan kernel pun tidak bisa lihat: cara kerja VBS, HVCI, dan Credential Guard
Pada instalasi bersih ke perangkat keras yang kompatibel, VBS diaktifkan secara bawaan dan memakai hypervisor serta SLAT untuk membuat is...
Kedalaman virtualisasi Windows (Bagian 3) — Mesin virtual yang boot dalam hitungan detik: mengapa WSL2, Windows Sandbox, dan kontainer begitu ringan
Mengapa WSL2 dan Windows Sandbox start dalam hitungan detik dan terasa begitu ringan? Artikel ini menjelaskan mekanismenya, dari dynamic ...
Kedalaman virtualisasi Windows (Bagian 1) — Di mana Windows Anda sebenarnya berjalan? Hypervisor dan partisi
Ketika Anda mengaktifkan Hyper-V, Windows host sendiri berjalan di atas hypervisor sebagai root partition. Artikel ini menjelaskan fondas...
Tampil di pencarian dengan nama daerah — Panduan praktis SEO lokal untuk UKM (halaman area dan Google Business Profile)
Untuk UKM yang situsnya tidak muncul saat orang mencari "nama daerah + bidang usaha". Artikel ini menata urutan perbaikan SEO lokal: meny...
Topik terkait
Halaman-halaman ini menempatkan topik dalam konteks layanan dan keputusan yang lebih luas.
Topik teknis Windows
Portal tentang pengembangan Windows, investigasi bug, dan pemanfaatan aset yang ada.
Layanan yang terkait dengan topik ini
Artikel ini berkaitan langsung dengan layanan berikut.
Pengembangan aplikasi Windows
Aplikasi bisnis, integrasi perangkat, dan alat komunikasi, dari kebutuhan hingga pengembangan.
Pertanyaan yang sering diajukan
Pertanyaan yang sering muncul dalam konsultasi tentang topik artikel ini.
- Bagaimana cara memilih antara named pipe dan TCP (soket localhost)?
- Untuk komunikasi antarpproses pada mesin yang sama, named pipe adalah kandidat pertama. Alasannya adalah model keamanannya. Sebuah pipe dapat mengendalikan "siapa yang boleh terhubung" di tingkat OS dengan Windows security descriptor (ACL), dan server dapat memeriksa serta meminjam akun Windows rekan yang terhubung dengan ImpersonateNamedPipeClient. Itu berbeda dari port TCP localhost, yang siapa pun bisa terhubung ke dalamnya, sehingga Anda harus menetapkan siapa rekan itu dengan autentikasi sendiri. Di sisi lain, opsi berbasis TCP menguntungkan bila komunikasi jarak jauh kemungkinan berkembang kemudian, bila Anda juga berbicara dengan proses di OS lain, atau bila Anda ingin memakai ulang aset protokol yang sudah ada seperti gRPC. Pertimbangan ini juga dijabarkan di artikel tentang memilih komunikasi antarpproses Windows.
- Haruskah saya memakai mode byte atau mode pesan?
- Jika Anda ingin memperlakukan "satu penulisan = satu satuan makna", mode pesan (PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE) lebih nyaman. Penerima dapat membaca dalam satuan yang ditulis pengirim, sehingga Anda tidak perlu mengelola batasnya sendiri. Mode byte adalah "aliran byte yang tak terputus" seperti TCP, dan Anda harus merancang framing sendiri — misalnya prefix panjang. Jika Anda membawa protokol yang sudah punya framing (misalnya bentuk terserialisasi berprefix panjang), mode byte sudah cukup. Satu peringatan: bahkan dalam mode pesan, jika buffer terima lebih kecil dari pesan, Anda mendapat pembacaan terbelah (ERROR_MORE_DATA), jadi itu tetap harus ditangani. Selain itu, mode baca adalah pengaturan per-handle, dan CreateNamedPipe menetapkannya hanya di sisi server. Klien harus menentukan PIPE_READMODE_MESSAGE dengan SetNamedPipeHandleState setelah CreateFile. Di .NET server menentukan PipeTransmissionMode.Message, dan klien mengatur NamedPipeClientStream.ReadMode ke Message setelah terhubung.
- Bagaimana cara membangun server yang berbicara dengan beberapa klien sekaligus?
- Named pipe dapat membuat beberapa instans dengan nama yang sama, dan satu instans menangani satu klien. Ada dua bentuk. Yang satu adalah desain sinkron yang menugaskan satu thread per klien; implementasinya lugas, tetapi mengonsumsi satu thread per klien. Yang lain adalah memakai I/O asinkron dengan FILE_FLAG_OVERLAPPED dan membiarkan sejumlah kecil thread menangani ConnectNamedPipe, ReadFile, dan WriteFile untuk setiap instans; sampel resmi Microsoft juga menunjukkan implementasi yang memproses beberapa instans pada satu thread. Di .NET Anda dapat menulis bentuk asinkron dengan kelugasan yang hampir sama seperti bentuk sinkron, memakai NamedPipeServerStream.WaitForConnectionAsync dan async/await. Kecuali ada alasan khusus, bentuk asinkron .NET yang saya rekomendasikan untuk implementasi baru.
- Apa minimum yang harus saya lakukan untuk keamanan named pipe?
- Empat poin. Pertama, jika koneksi jarak jauh tidak diperlukan, tentukan PIPE_REJECT_REMOTE_CLIENTS dan tolak secara eksplisit koneksi lewat jaringan. Kedua, tetapkan ACL yang sesuai dengan SECURITY_ATTRIBUTES dan persempit pengguna serta grup yang boleh terhubung (ACL bawaan terlalu longgar untuk sebagian penggunaan). Ketiga, tentukan FILE_FLAG_FIRST_PIPE_INSTANCE saat membuat instans pertama, agar Anda mendeteksi "pembajakan nama" di mana pipe dengan nama yang sama dibuat lebih dulu (jangan pasang flag ini pada instans kedua dan seterusnya). Keempat, klien yang hanya ingin diidentifikasi server harus menentukan SECURITY_SQOS_PRESENT|SECURITY_IDENTIFICATION pada CreateFile, agar server palsu tidak dapat meminjam (meng-impersonate) haknya. Dalam desain broker di mana server melakukan akses sungguhan di bawah hak klien, impersonation harus diizinkan, jadi pembatasan ini dipakai atau tidak tergantung apakah desain itu membiarkan server meminjam hak.
- Apakah ada hal yang perlu diwaspadai saat memakai ImpersonateNamedPipeClient?
- Yang paling penting adalah memeriksa nilai kembalian. Jika Anda lanjut setelah impersonation gagal, operasi berikutnya berjalan dengan hak proses server sendiri (sering kali tinggi), dan operasi yang seharusnya tidak diizinkan bagi klien ikut lolos. Dokumentasi resmi juga menyatakan secara eksplisit bahwa saat gagal Anda tidak boleh mengeksekusi permintaan klien. Anda juga perlu memanggilnya hanya setelah membaca sesuatu — impersonation dilakukan dalam konteks "pesan terakhir yang dibaca dari pipe" — dan kembali secara andal ke konteks semula dengan RevertToSelf setelah pekerjaan selesai. Mekanisme seputar impersonation (token, tingkat impersonation, SeImpersonatePrivilege) dibahas secara rinci di artikel tentang token impersonation.
Profil penulis
Halaman perkenalan penulis artikel.
Go Komura
Direktur KomuraSoft LLC
Berspesialisasi dalam pengembangan perangkat lunak Windows, konsultasi teknis, dan investigasi bug, terutama pada proyek dengan sistem yang sudah ada dan bug yang sulit direproduksi.