cpp
examples
examples.cpp⚙️cpp
/**
* Networking - Examples
* Compile: g++ -std=c++17 -Wall examples.cpp -o examples
*
* Note: Run server and client in separate terminals
*/
#include <iostream>
#include <string>
#include <cstring>
#include <thread>
#include <vector>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
const int PORT = 8888;
const int BUFFER_SIZE = 1024;
// ============================================================
// SECTION 1: TCP CLIENT
// ============================================================
class TCPClient {
int sock;
bool connected = false;
public:
TCPClient() : sock(-1) {}
bool connectTo(const string& host, int port) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
cerr << "Failed to create socket" << endl;
return false;
}
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
if (inet_pton(AF_INET, host.c_str(), &serverAddr.sin_addr) <= 0) {
cerr << "Invalid address" << endl;
return false;
}
if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
cerr << "Connection failed" << endl;
return false;
}
connected = true;
cout << " Connected to " << host << ":" << port << endl;
return true;
}
bool sendData(const string& data) {
if (!connected) return false;
ssize_t sent = send(sock, data.c_str(), data.length(), 0);
return sent == (ssize_t)data.length();
}
string receive() {
if (!connected) return "";
char buffer[BUFFER_SIZE];
ssize_t bytes = recv(sock, buffer, BUFFER_SIZE - 1, 0);
if (bytes > 0) {
buffer[bytes] = '\0';
return string(buffer);
}
return "";
}
void disconnect() {
if (sock >= 0) {
close(sock);
sock = -1;
connected = false;
}
}
~TCPClient() { disconnect(); }
};
// ============================================================
// SECTION 2: TCP SERVER
// ============================================================
class TCPServer {
int serverSock;
bool running = false;
public:
TCPServer() : serverSock(-1) {}
bool start(int port) {
serverSock = socket(AF_INET, SOCK_STREAM, 0);
if (serverSock < 0) {
cerr << "Failed to create socket" << endl;
return false;
}
// Allow address reuse
int opt = 1;
setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
if (bind(serverSock, (sockaddr*)&addr, sizeof(addr)) < 0) {
cerr << "Bind failed" << endl;
return false;
}
if (listen(serverSock, 5) < 0) {
cerr << "Listen failed" << endl;
return false;
}
running = true;
cout << " Server listening on port " << port << endl;
return true;
}
void handleClient(int clientSock) {
char buffer[BUFFER_SIZE];
while (true) {
ssize_t bytes = recv(clientSock, buffer, BUFFER_SIZE - 1, 0);
if (bytes <= 0) break;
buffer[bytes] = '\0';
cout << " Received: " << buffer << endl;
// Echo back
string response = "Echo: " + string(buffer);
send(clientSock, response.c_str(), response.length(), 0);
}
close(clientSock);
cout << " Client disconnected" << endl;
}
void acceptOne() {
sockaddr_in clientAddr;
socklen_t clientLen = sizeof(clientAddr);
int clientSock = accept(serverSock, (sockaddr*)&clientAddr, &clientLen);
if (clientSock >= 0) {
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);
cout << " Client connected from " << clientIP << endl;
handleClient(clientSock);
}
}
void stop() {
if (serverSock >= 0) {
close(serverSock);
serverSock = -1;
running = false;
}
}
~TCPServer() { stop(); }
};
// ============================================================
// SECTION 3: UDP EXAMPLE
// ============================================================
class UDPSocket {
int sock;
public:
UDPSocket() {
sock = socket(AF_INET, SOCK_DGRAM, 0);
}
bool bindTo(int port) {
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
return bind(sock, (sockaddr*)&addr, sizeof(addr)) >= 0;
}
bool sendTo(const string& host, int port, const string& data) {
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, host.c_str(), &addr.sin_addr);
return sendto(sock, data.c_str(), data.length(), 0,
(sockaddr*)&addr, sizeof(addr)) >= 0;
}
string receiveFrom(string& senderIP, int& senderPort) {
char buffer[BUFFER_SIZE];
sockaddr_in senderAddr;
socklen_t senderLen = sizeof(senderAddr);
ssize_t bytes = recvfrom(sock, buffer, BUFFER_SIZE - 1, 0,
(sockaddr*)&senderAddr, &senderLen);
if (bytes > 0) {
buffer[bytes] = '\0';
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &senderAddr.sin_addr, ip, INET_ADDRSTRLEN);
senderIP = ip;
senderPort = ntohs(senderAddr.sin_port);
return string(buffer);
}
return "";
}
~UDPSocket() { close(sock); }
};
// ============================================================
// DEMO FUNCTIONS
// ============================================================
void demoTCPEcho() {
cout << "--- TCP Echo Demo ---" << endl;
cout << " (Server and client in same process for demo)" << endl;
// This would normally be separate processes
// Just showing the API usage
TCPServer server;
if (!server.start(PORT)) {
cout << " Server failed to start" << endl;
return;
}
// In real usage, client would be in separate process
cout << " Server started on port " << PORT << endl;
cout << " (Demo complete - run server/client separately for real test)" << endl;
server.stop();
}
void demoSocketInfo() {
cout << "\n--- Socket Information ---" << endl;
// Address conversion
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr);
// Convert back to string
char ipStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr.sin_addr, ipStr, INET_ADDRSTRLEN);
cout << " IP: " << ipStr << endl;
cout << " Port: " << ntohs(addr.sin_port) << endl;
// Byte order
cout << "\n Byte order functions:" << endl;
cout << " htons(1234) = " << htons(1234) << endl;
cout << " htonl(12345678) = " << htonl(12345678) << endl;
}
void demoUDP() {
cout << "\n--- UDP Demo ---" << endl;
UDPSocket sock;
cout << " UDP socket created" << endl;
cout << " (Bind/send/receive work similarly to TCP)" << endl;
}
// ============================================================
// SIMPLE ECHO SERVER (Standalone)
// ============================================================
void runEchoServer() {
cout << "\n--- Running Echo Server ---" << endl;
int serverSock = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT);
bind(serverSock, (sockaddr*)&addr, sizeof(addr));
listen(serverSock, 5);
cout << " Echo server on port " << PORT << endl;
cout << " (Press Ctrl+C to stop)" << endl;
cout << " Test with: nc localhost " << PORT << endl;
while (true) {
sockaddr_in clientAddr;
socklen_t clientLen = sizeof(clientAddr);
int clientSock = accept(serverSock, (sockaddr*)&clientAddr, &clientLen);
if (clientSock >= 0) {
cout << " Client connected" << endl;
char buffer[BUFFER_SIZE];
ssize_t bytes;
while ((bytes = recv(clientSock, buffer, BUFFER_SIZE, 0)) > 0) {
send(clientSock, buffer, bytes, 0);
}
close(clientSock);
cout << " Client disconnected" << endl;
}
}
close(serverSock);
}
// ============================================================
// MAIN
// ============================================================
int main(int argc, char* argv[]) {
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ NETWORKING - EXAMPLES ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
if (argc > 1 && string(argv[1]) == "server") {
runEchoServer();
return 0;
}
demoSocketInfo();
demoTCPEcho();
demoUDP();
cout << "\n--- How to Test ---" << endl;
cout << " 1. Run: ./examples server" << endl;
cout << " 2. In another terminal: nc localhost " << PORT << endl;
cout << " 3. Type messages - they'll be echoed back" << endl;
cout << "\n=== Complete ===" << endl;
return 0;
}