In this guide, we will explore how to write TCP and UDP clients and servers in C++. TCP (Transmission Control Protocol) is a connection-oriented protocol that guarantees delivery of packets, while UDP (User Datagram Protocol) is a connectionless protocol that does not guarantee delivery, order, or error checking.
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sock;
struct sockaddr_in server;
char *message;
char server_ip[] = "127.0.0.1"; // Localhost
int port = 8080;
// Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
std::cerr << "Could not create socket" << std::endl;
return 1;
}
// Setup server structure
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(server_ip);
// Connect to server
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
std::cerr << "Connect failed" << std::endl;
return 1;
}
// Send data
message = "Hello Server";
send(sock, message, strlen(message), 0);
std::cout << "Data sent: " << message << std::endl;
// Close socket
close(sock);
return 0;
}
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sockfd, client_sock, c;
struct sockaddr_in server, client;
char buffer[2000];
// Create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
std::cerr << "Could not create socket" << std::endl;
return 1;
}
// Setup server structure
server.sin_family = AF_INET;
server.sin_port = htons(8080);
server.sin_addr.s_addr = INADDR_ANY;
// Bind
if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) {
std::cerr << "Bind failed" << std::endl;
return 1;
}
// Listen
listen(sockfd, 3);
c = sizeof(struct sockaddr_in);
// Accept connection from client
client_sock = accept(sockfd, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0) {
std::cerr << "Accept failed" << std::endl;
return 1;
}
// Receive data
recv(client_sock, buffer, 2000, 0);
std::cout << "Data received: " << buffer << std::endl;
// Close sockets
close(client_sock);
close(sockfd);
return 0;
}
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sock;
struct sockaddr_in server;
char *message;
char server_ip[] = "127.0.0.1";
int port = 8080;
// Create socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
std::cerr << "Could not create socket" << std::endl;
return 1;
}
// Setup server structure
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(server_ip);
// Send data
message = "Hello UDP Server";
sendto(sock, message, strlen(message), 0, (struct sockaddr *)&server, sizeof(server));
std::cout << "Data sent: " << message << std::endl;
// Close socket
close(sock);
return 0;
}
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sock;
struct sockaddr_in server, client;
char buffer[2000];
socklen_t client_len = sizeof(client);
// Create socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
std::cerr << "Could not create socket" << std::endl;
return 1;
}
// Setup server structure
server.sin_family = AF_INET;
server.sin_port = htons(8080);
server.sin_addr.s_addr = INADDR_ANY;
// Bind
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
std::cerr << "Bind failed" << std::endl;
return 1;
}
// Receive data
recvfrom(sock, buffer, 2000, 0, (struct sockaddr *)&client, &client_len);
std::cout << "Data received: " << buffer << std::endl;
// Close socket
close(sock);
return 0;
}
How do I avoid rehashing overhead with std::set in multithreaded code?
How do I find elements with custom comparators with std::set for embedded targets?
How do I erase elements while iterating with std::set for embedded targets?
How do I provide stable iteration order with std::unordered_map for large datasets?
How do I reserve capacity ahead of time with std::unordered_map for large datasets?
How do I erase elements while iterating with std::unordered_map in multithreaded code?
How do I provide stable iteration order with std::map for embedded targets?
How do I provide stable iteration order with std::map in multithreaded code?
How do I avoid rehashing overhead with std::map in performance-sensitive code?
How do I merge two containers efficiently with std::map for embedded targets?