Server Echo Sederhana
Layani banyak klien sekaligus.
Server Echo Sederhana 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.
Yang Akan Kita Bangun
Server echo menerima koneksi TCP dan mengirimkan kembali byte apa pun yang dikirim klien. Ini adalah "hello world" dalam pemrograman jaringan.
Kita akan membangunnya di atas epoll agar satu utas dapat melayani banyak klien sekaligus. Bagian-bagiannya adalah: soket pendengar, perulangan epoll, serta penanganan baca-lalu-tulis untuk setiap klien.
Membuat Soket Pendengar
Mulailah dengan socket() untuk titik akhir TCP IPv4. Tiga parameternya adalah AF_INET, SOCK_STREAM, dan protokol 0.
Fungsi ini mengembalikan deskriptor berkas yang akan kita ikat, atur agar tidak memblokir, lalu daftarkan ke epoll. Periksa nilai -1 pada setiap pemanggilan sistem.
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd == -1) { perror("socket"); exit(1); }Menggunakan Kembali Alamat
Sebelum mengikat, tetapkan SO_REUSEADDR dengan setsockopt(). Ini memungkinkan server dimulai ulang dan diikat kembali ke port yang sama tanpa menunggu status TIME_WAIT berakhir.
Tanpa pengaturan ini, mulai ulang dengan cepat sering gagal dengan EADDRINUSE, sebuah kejutan yang menjengkelkan selama pengembangan.
int yes = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);Mengikat ke Port
Isi struct sockaddr_in dengan keluarga, port, dan alamat. Gunakan htons() untuk port dan INADDR_ANY agar dapat mendengarkan pada semua antarmuka.
Kemudian panggil bind() untuk mengaitkan soket dengan alamat tersebut. htons mengonversi urutan byte host menjadi urutan byte jaringan, yang diperlukan.
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(8080);
bind(listen_fd, (struct sockaddr*)&addr, sizeof addr);Mendengarkan dan Beralih ke Mode Tanpa Pemblokiran
Panggil listen() untuk menandai soket sebagai pasif dan menetapkan backlog untuk koneksi yang menunggu. SOMAXCONN meminta batas maksimum sistem.
Kemudian ubah soket ke mode tanpa pemblokiran agar accept() tidak pernah menghentikan perulangan peristiwa. Kini soket siap didaftarkan ke epoll.
listen(listen_fd, SOMAXCONN);
set_nonblocking(listen_fd);Mendaftarkan Pendengar
Buat instans epoll dan tambahkan soket pendengar dengan EPOLLIN. Peristiwa yang dapat dibaca di sini berarti ada klien baru yang menunggu untuk diterima.
Kita menyimpan fd di data.fd agar dapat mengenali pendengar di dalam perulangan.
int epfd = epoll_create1(0);
struct epoll_event ev = { .events = EPOLLIN, .data.fd = listen_fd };
epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev);Menerima Klien
Saat pendengar dapat dibaca, lakukan perulangan pada accept() hingga EAGAIN. Setiap soket klien baru diatur agar tidak memblokir dan didaftarkan untuk EPOLLIN.
Mulai saat ini, epoll akan memberi tahu kita setiap kali klien mengirimkan data yang dapat kita kirim kembali.
int c = accept(listen_fd, NULL, NULL);
if (c != -1) {
set_nonblocking(c);
struct epoll_event cev = { .events = EPOLLIN, .data.fd = c };
epoll_ctl(epfd, EPOLL_CTL_ADD, c, &cev);
}Logika Echo
Untuk klien yang siap, terima data dengan recv() ke dalam penyangga. Jika Anda mendapatkan byte, kirimkan byte yang sama langsung kembali dengan send().
Pembacaan lalu penulisan sederhana ini adalah echo. Dalam lingkungan produksi, Anda akan menyangga byte yang belum terkirim, tetapi untuk demonstrasi kita mengasumsikan balasan kecil tersebut muat di penyangga pengiriman.
char buf[4096];
ssize_t r = recv(fd, buf, sizeof buf, 0);
if (r > 0) {
send(fd, buf, r, 0);
}Mendeteksi Pemutusan Koneksi
Nilai kembalian recv() sebesar 0 berarti klien melakukan penghentian secara tertib. Nilai kembalian negatif dengan apa pun selain EAGAIN adalah kesalahan nyata.
Dalam kedua kasus tersebut, hapus deskriptor dari epoll dan panggil close() untuk membebaskan sumber daya serta menghentikan peristiwa berikutnya.
if (r == 0 || (r < 0 && errno != EAGAIN)) {
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
close(fd);
}Perulangan Lengkap
Gabungkan semua bagian: tunggu peristiwa, tentukan apakah deskriptornya adalah pendengar atau klien, lalu lakukan tindakan yang sesuai.
Perulangan ringkas ini merupakan server echo serentak yang berfungsi penuh. Satu utas, banyak klien, tanpa utas terpisah untuk setiap koneksi.
for (;;) {
int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; i++) {
if (events[i].data.fd == listen_fd) accept_clients();
else echo_or_close(events[i].data.fd);
}
}Menguji dan Langkah Berikutnya
Kompilasi di Linux dan hubungkan dengan nc localhost 8080; apa pun yang Anda ketik akan dikirim kembali. Buka beberapa terminal untuk membuktikan bahwa koneksi berjalan serentak.
Untuk membuatnya lebih tangguh: sangga pengiriman sebagian, tangani EPOLLOUT, beralih ke EPOLLET dengan pengosongan penuh, dan tangani EPOLLRDHUP untuk penutupan sebagian.
Pemeriksaan Singkat
Uji pemahaman Anda tentang alur server echo.
Rangkuman
Anda telah membuat server gema epoll: membuatnya, mengatur SO_REUSEADDR, mengikatnya, membuatnya mendengarkan, dan menjadikannya nonblokir. Daftarkan pendengar, terima klien dalam sebuah perulangan, lalu kirim kembali pesan dengan recv()/send().
Perlakukan nilai balik 0 sebagai pemutusan koneksi dan tutup koneksi dengan rapi. Dari kerangka ini, Anda dapat mengembangkan server jaringan satu utas berperforma tinggi.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Server Echo Sederhana” gratis?
Ya — teks lengkap “Server Echo Sederhana” 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 “Server Echo Sederhana”?
Layani banyak klien sekaligus. 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 “Server Echo Sederhana” 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
- I/O Memblokir vs Tidak Memblokir
- Menyiapkan epoll
- Loop Peristiwa
- Server Echo Sederhana