Episode ini membuka pemrograman jaringan dengan sockets: perbedaan TCP dan UDP, API socket mulai dari socket, bind, listen, accept, connect, send, dan recv, pembuatan client-server sederhana, serta network byte order, socket address, dan error handling.

Bahasa C adalah bahasa kelahiran internet: TCP/IP stack, DNS resolver, dan HTTP server pertama semuanya ditulis dalam C. Episode 12 membawa kalian ke level tersebut dengan mempelajari socket programming — cara program berbicara satu sama lain melalui jaringan.
Kita akan membahas dua protokol utama: TCP yang andal dan terurut untuk transfer data, serta UDP yang cepat dan ringan untuk aplikasi real-time. API socket yang kalian pelajari akan terlihat familier karena menjadi fondasi bahasa dan framework lain.
Di akhir episode, kalian akan membangun server dan client TCP yang nyata, lengkap dengan penanganan network byte order dan error handling — keterampilan inti untuk episode 13 dan 14.
TCP menyediakan koneksi yang andal: data sampai urut, tidak hilang, dan ada mekanisme pengakuan. UDP hanya mengirim datagram tanpa jaminan sampai. Pilih TCP untuk HTTP, database, dan file transfer. Pilih UDP untuk streaming, game, dan DNS di mana kecepatan lebih penting daripada jaminan pengiriman.
Alur TCP socket di sisi server: socket membuat socket, bind mengikat ke alamat dan port, listen mulai mendengarkan, accept menerima koneksi, lalu send dan recv bertukar data. Sisi client lebih pendek: socket, connect, lalu send dan recv.
Server TCP dimulai dengan membuat socket dan mengikatnya ke alamat:
cat > server.c <<'EOF'
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(void) {
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return 1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return 1;
}
if (listen(fd, 8) < 0) {
perror("listen");
return 1;
}
printf("server mendengarkan port 8080\n");
close(fd);
return 0;
}
EOF
gcc -Wall -Wextra server.c -o server && ./serverPanggilan socket(AF_INET, SOCK_STREAM, 0) membuat socket IPv4 berbasis TCP. htons(8080) mengubah port dari urutan byte host ke network byte order (big-endian), dan INADDR_ANY berarti mendengarkan di semua antarmuka. listen(fd, 8) menetapkan panjang antrian koneksi menunggu.
Setelah listen, server memanggil accept untuk menerima koneksi masuk, dan client memanggil connect:
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(void) {
int fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect");
return 1;
}
close(fd);
return 0;
}
EOF
gcc -Wall -Wextra client.c -o clientinet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) mengubah teks alamat menjadi biner. Fungsi ini lebih aman daripada inet_addr karena bisa memeriksa validitas format. Untuk nama host seperti localhost, gunakan getaddrinfo yang menangani DNS dan IPv6 sekaligus.
Server lengkap menerima koneksi dan bertukar pesan. Perhatikan bahwa server memakai alamat dari accept, bukan dari variabel statis:
int klien = accept(fd, (struct sockaddr *)NULL, NULL);
if (klien < 0) {
perror("accept");
return 1;
}
char buffer[256];
ssize_t n = recv(klien, buffer, sizeof(buffer) - 1, 0);
if (n > 0) {
buffer[n] = '\0';
printf("diterima: %s\n", buffer);
}
close(klien);
close(fd);accept(fd, (struct sockaddr *)NULL, NULL) memblokir sampai ada koneksi masuk dan mengembalikan socket baru khusus untuk koneksi itu. recv mengembalikan jumlah byte yang dibaca, atau -1 saat error, dan 0 saat koneksi ditutup lawan.
Untuk menguji server tanpa menulis client, gunakan nc di terminal lain:
nc 127.0.0.1 8080Perintah nc 127.0.0.1 8080 membuka koneksi TCP ke server dan mengirim apa pun yang kalian ketik. Ini contoh nyata memakai tool eksternal untuk memvalidasi program — kebiasaan yang sangat berguna di episode 22.
Arsitektur komputer menyimpan bilangan dalam urutan byte yang berbeda. Karena jaringan memakai big-endian, semua port dan alamat yang melewati socket harus dikonversi. Empat fungsi pembantu: htons, htonl, ntohs, ntohl. Aturan sederhana: host-to-network saat mengirim, network-to-host saat menerima.
Semua panggilan socket bisa gagal: socket kehabisan deskriptor, bind port sudah dipakai, connect menolak koneksi, dan recv terputus. Periksa nilai kembalian setiap panggilan dan gunakan perror untuk pesan yang jelas:
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind gagal");
return 1;
}Pola if (bind(...) < 0) { perror(...); return 1; } menangkap error lebih awal dan meninggalkan jejak yang jelas. Socket yang sudah dibuka wajib ditutup dengan close di semua jalur, termasuk saat error.
Warning
Server contoh di atas hanya melayani satu koneksi karena accept dipanggil sekali. Untuk melayani banyak client sekaligus, kalian perlu loop atau multithreading — tepatnya topik episode 16, dan penggantian accept blokir dengan select atau poll di episode 18.
Inti yang harus dibawa pulang:
Di episode 13 selanjutnya kita akan membahas security dan safe coding — buffer overflow, format string vulnerabilities, dan mitigasinya, secure coding dengan bounds checking serta strncpy dan snprintf, perbedaan stack dan heap overflow, hingga input validation dan defensive programming.