Episode ini membahas dasar networking di C++: socket programming TCP dan UDP dengan BSD sockets, komunikasi client-server dan desain protokol sederhana, byte order dan address structures, error handling, serta pertimbangan cross-platform di Windows dan Linux.

Hampir semua sistem modern berkomunikasi lewat jaringan — HTTP, database, message queue, hingga game multiplayer. Di C++, komunikasi jaringan memakai socket: antarmuka yang dikelola sistem operasi untuk mengirim dan menerima data. Socket yang paling dasar berasal dari BSD sockets, standar yang dipakai di Linux dan diadopsi Windows lewat Winsock.
Episode 13 membangun dasar networking: konsep socket dan model client-server, server dan client TCP sederhana, pentingnya byte order, address structures, error handling, serta perbedaan API antara Windows dan Linux.
Socket adalah titik akhir komunikasi yang diidentifikasi oleh alamat IP dan port. TCP menyediakan koneksi yang andal dan berurutan, cocok untuk data yang tidak boleh hilang. UDP tanpa koneksi, cepat tetapi bisa kehilangan paket, cocok untuk streaming dan game. Model yang paling umum adalah client-server: server mendengarkan di port, client terhubung ke port tersebut.
Alur kerja lengkapnya:
socket() -> bind() -> listen() -> accept() -> recv()/send() [server]
socket() -> connect() -> send()/recv() [client]Alur socket() -> bind() -> listen() -> accept() adalah siklus hidup socket server, sedangkan client cukup socket() -> connect() lalu bertukar data. Keduanya memakai header <sys/socket.h>, <netinet/in.h>, dan <arpa/inet.h> di Linux.
Server membuat socket dengan socket(), mengikatnya ke port dengan bind(), mendengarkan dengan listen(), lalu menerima koneksi dengan accept():
cat > server.cpp <<'EOF'
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
std::cerr << "gagal membuat socket\n";
return 1;
}
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
std::cerr << "gagal bind\n";
return 1;
}
listen(fd, 5);
sockaddr_in client{};
socklen_t len = sizeof(client);
int cfd = accept(fd, reinterpret_cast<sockaddr*>(&client), &len);
std::cout << "Client terhubung\n";
char buf[256];
int n = recv(cfd, buf, sizeof(buf), 0);
buf[n] = '\0';
std::cout << "Terima: " << buf << "\n";
send(cfd, "pong", 4, 0);
close(cfd);
close(fd);
}
EOF
g++ -std=c++20 server.cpp -o serversocket(AF_INET, SOCK_STREAM, 0) membuat TCP socket. htons(8080) mengonversi port ke network byte order. bind(fd, ...) mengikat socket ke port 8080, listen(fd, 5) mengizinkan 5 antrian koneksi, dan accept() menunggu koneksi masuk. Header <unistd.h> menyediakan close.
Client membuat socket lalu connect ke alamat dan port server:
cat > client.cpp <<'EOF'
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int fd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in 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, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) {
std::cerr << "koneksi gagal\n";
return 1;
}
send(fd, "ping", 4, 0);
char buf[256];
int n = recv(fd, buf, sizeof(buf), 0);
buf[n] = '\0';
std::cout << "Server: " << buf << "\n";
close(fd);
}
EOF
g++ -std=c++20 client.cpp -o clientinet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) mengubah string alamat menjadi binary, dan connect(fd, ...) menghubungkan ke server di port 8080. Alamat 127.0.0.1 adalah loopback — server dan client di mesin yang sama.
Jalankan server lalu uji dengan netcat tanpa menulis client: perintah nc 127.0.0.1 8080 memakai netcat untuk menguji server. Ketik teks, tekan Enter, dan server menerimanya. Netcat adalah tool debugging jaringan yang wajib dikuasai.
Mesin menyimpan angka dalam urutan byte berbeda: little-endian (umum di x86) menyimpan byte terkecil lebih dulu, big-endian (network order) sebaliknya. Jaringan memakai big-endian, jadi semua nilai dikonversi saat dikirim dan diterima dengan htons dan htonl (host ke network) serta ntohs dan ntohl (sebaliknya). Tanpa konversi htons(port), port terbaca salah di mesin dengan byte order berbeda — bug klasik dalam komunikasi antar arsitektur.
sockaddr_in menyimpan alamat IPv4 dengan tiga field penting: sin_family (AF_INET), sin_port (port dalam network order), dan sin_addr (alamat IP biner). Untuk IPv6, gunakan sockaddr_in6. Aplikasi produksi biasanya membungkus semua ini dalam abstraksi agar tidak menyentuh detail per-OS.
Setiap fungsi socket mengembalikan nilai yang harus diperiksa. errno menjelaskan penyebab kegagalan, dan pola strerror(errno) mengubahnya menjadi pesan deskriptif seperti Address already in use. Kesalahan umum: port sudah dipakai proses lain, atau bind tanpa hak istimewa untuk port di bawah 1024.
Di Windows, socket memakai Winsock: header <winsock2.h>, panggilan WSAStartup sebelum memakai socket, closesocket alih-alih close, dan link library ws2_32. Abstraksi lintas platform memilih header saat preprocessing:
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <unistd.h>
#endifBlok #ifdef _WIN32 memilih header sesuai platform saat preprocessing. Ini pola conditional compilation yang akan kalian pelajari lebih dalam di episode 20.
Tip
Untuk aplikasi produksi, pertimbangkan library jaringan seperti Boost.Asio atau standalone asio yang menyatukan Windows dan Linux.
Inti yang harus dibawa pulang:
htons dan htonl mengonversi nilai ke network byte order.strerror(errno).Di episode 14 selanjutnya kita akan membahas secure coding dan safety — memory safety dan mitigasi buffer overflow, penggunaan aman C string API versus std::string, input validation dan sanitasi dengan boundary checks, serta cybersecurity best practices untuk kode C++.