Menangani Banyak Klien
select dan poll.
Menangani Banyak Klien adalah pelajaran C Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C Academy mencakup 4 pelajaran total.
Masalah Konkurensi
Server sederhana menangani satu klien pada satu waktu. Jika sebuah klien lambat, semua klien lainnya harus menunggu. Untuk melayani banyak klien secara bersamaan, Anda memerlukan model yang berbeda.
Pendekatan untuk Konkurensi
Tiga strategi umum:
- Satu thread/proses per klien: sederhana, tetapi membutuhkan banyak sumber daya saat skala meningkat
- Multiplexing I/O dengan
selectataupoll: satu thread mengawasi banyak socket - Perulangan peristiwa dengan
epoll/kqueue: dapat menangani hingga ribuan koneksi
Fungsi select
select() mengawasi sekumpulan deskriptor berkas dan memberi tahu Anda mana yang siap untuk dibaca, ditulis, atau mengalami kesalahan, semuanya dalam satu pemanggilan yang memblokir. Dengan demikian, satu thread dapat melayani banyak socket.
Dasar-dasar fd_set
select menggunakan bitmask fd_set. Kelola bitmask tersebut dengan makro: FD_ZERO, FD_SET, FD_CLR, dan FD_ISSET.
#include <sys/select.h>
void setup_set(fd_set *set, int listen_fd) {
FD_ZERO(set); /* clear all */
FD_SET(listen_fd, set); /* watch the listener */
}Memanggil select
select memerlukan fd tertinggi ditambah satu, dan mengubah set secara langsung untuk menandai deskriptor yang siap. Karena proses ini bersifat destruktif, Anda harus membangun ulang set sebelum setiap pemanggilan.
#include <sys/select.h>
#include <stdio.h>
int wait_ready(int maxfd, fd_set *read_set) {
int n = select(maxfd + 1, read_set, NULL, NULL, NULL);
if (n < 0) perror("select");
return n; /* number of ready fds */
}Perulangan Server select
Polanya: bangun ulang set, panggil select, lalu untuk setiap fd yang siap, terima klien baru jika fd tersebut adalah pendengar, atau baca data jika fd tersebut milik klien.
#include <sys/select.h>
void loop_skeleton(int listen_fd, fd_set *master, int maxfd) {
fd_set work;
for (;;) {
work = *master; /* copy, select destroys it */
select(maxfd + 1, &work, NULL, NULL, NULL);
for (int fd = 0; fd <= maxfd; fd++) {
if (!FD_ISSET(fd, &work)) continue;
/* fd == listen_fd -> accept; else -> recv */
}
}
}Melacak Klien
Saat Anda menerima koneksi baru, tambahkan fd-nya ke set utama dan perbarui maxfd. Saat klien terputus (recv mengembalikan 0), lakukan close pada fd tersebut dan hapus dari set dengan FD_CLR.
#include <sys/select.h>
#include <unistd.h>
void add_client(fd_set *master, int *maxfd, int conn) {
FD_SET(conn, master);
if (conn > *maxfd) *maxfd = conn;
}
void drop_client(fd_set *master, int conn) {
close(conn);
FD_CLR(conn, master);
}Keterbatasan select
select memiliki beberapa kekurangan:
- Dibatasi hingga
FD_SETUPdeskriptor (sering kali 1024) - Memindai semua fd dengan kompleksitas O(n) pada setiap pemanggilan
- Set harus dibangun ulang pada setiap iterasi
Untuk banyak koneksi, poll atau epoll dapat menangani skala yang lebih besar.
Keunggulan poll
poll() menerima array struct pollfd, bukan bitmask tetap, sehingga tidak memiliki batas 1024 deskriptor dan tidak merusak input pada setiap pemanggilan.
#include <poll.h>
void setup_poll(struct pollfd *pfd, int listen_fd) {
pfd[0].fd = listen_fd;
pfd[0].events = POLLIN; /* notify when readable */
}Memanggil poll
poll memblokir hingga setidaknya satu fd siap (atau batas waktu tercapai), lalu mengatur revents pada setiap entri yang siap.
#include <poll.h>
#include <stdio.h>
int poll_ready(struct pollfd *pfds, int count) {
int n = poll(pfds, count, -1); /* -1 = block forever */
if (n < 0) perror("poll");
return n;
}Meningkatkan Skala: epoll
Untuk ribuan koneksi, epoll milik Linux (dan kqueue milik BSD) hanya mengirimkan deskriptor yang siap dengan kompleksitas O(1) per peristiwa, sehingga menghindari pemindaian penuh yang dilakukan oleh select dan poll.
Pemeriksaan Singkat
Uji pemahaman Anda tentang penanganan banyak klien.
Ringkasan
Anda telah mempelajari cara melayani banyak klien dengan satu thread.
selectmengawasi banyak fd; kelola dengan makro FD_- Bangun ulang set pada setiap perulangan karena select bersifat destruktif
- Tambahkan klien yang diterima ke set; hapus saat terputus
pollmenghindari batas 1024;epolldapat menangani hingga ribuan koneksi
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Menangani Banyak Klien” gratis?
Ya — teks lengkap “Menangani Banyak Klien” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C Academy, upgrade ke CoddyKit PRO. Kursus C Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Menangani Banyak Klien”?
select dan poll. Kamu berlatih C Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C Academy?
Tidak diperlukan pengalaman sebelumnya. C Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Menangani Banyak Klien” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C Academy ini?
Ya. Setiap pelajaran C Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Gambaran Umum Socket
- Server TCP
- Klien TCP
- Menangani Banyak Klien