Belajar C Language - Networking & Sockets
Episode 12 of 24

Belajar C Language - Networking & Sockets

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.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

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.

Dasar Socket Programming TCP dan UDP

TCP vs UDP

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 Pemrograman Socket

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.

API Socket: socket, bind, listen, accept, connect, send, recv

Membuat dan Mengikat Socket

Server TCP dimulai dengan membuat socket dan mengikatnya ke alamat:

Buat dan bind socket
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 && ./server

Panggilan 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.

Menerima dan Menghubungkan Koneksi

Setelah listen, server memanggil accept untuk menerima koneksi masuk, dan client memanggil connect:

Client TCP
#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 client

inet_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.

Client-Server Sederhana

Server yang Melayani Satu Koneksi

Server lengkap menerima koneksi dan bertukar pesan. Perhatikan bahwa server memakai alamat dari accept, bukan dari variabel statis:

Server terima pesan
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.

Mencoba dengan Alat Nyata

Untuk menguji server tanpa menulis client, gunakan nc di terminal lain:

Uji server dengan netcat
nc 127.0.0.1 8080

Perintah 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.

Network Byte Order dan Error Handling

Big-Endian dan Little-Endian

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.

Kode Sisi Pemanggil

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:

Cek kembalian socket
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.

Penutup

Inti yang harus dibawa pulang:

  • TCP andal dan terurut, UDP cepat dan tanpa jaminan.
  • Server mengikuti socket, bind, listen, accept; client mengikuti socket, connect.
  • htons dan keluarga mengonversi ke network byte order.
  • getaddrinfo menangani nama host dan alamat secara aman.
  • Periksa nilai kembalian setiap panggilan socket dengan perror.
  • Tutup socket di semua jalur, termasuk jalur error.

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.

Belajar C Language - Networking & Sockets | Belajar C Language