Sample Title: Echo Server
Category: Windows Networking
Description: This sample demonstrates the fundamental principles of creating a simple TCP echo server using Windows Sockets (Winsock). When a client connects, the server reads data sent by the client and echoes it back. This is a basic building block for understanding network communication.
This project provides a C++ implementation of a basic TCP echo server. It listens for incoming connections on a specified port, accepts them, and then enters a loop to receive data from the connected client and send the same data back. This allows for simple testing of network connectivity and basic socket programming.
EchoServer.cpp - The main source file for the server implementation.README.md - Provides instructions on how to build and run the sample.EchoClient.cpp - (Optional) A companion client sample to test the server.EchoServer.cpp (Excerpt)Below is a simplified excerpt of the core logic found in EchoServer.cpp:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#pragma comment(lib, "Ws2_32.lib")
int main() {
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
std::cerr << "WSAStartup failed: " << iResult << std::endl;
return 1;
}
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
std::cerr << "socket failed with error: " << WSAGetLastError() << std::endl;
WSACleanup();
return 1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888); // Port to listen on
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(ListenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cerr << "bind failed with error: " << WSAGetLastError() << std::endl;
closesocket(ListenSocket);
WSACleanup();
return 1;
}
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
std::cerr << "listen failed with error: " << WSAGetLastError() << std::endl;
closesocket(ListenSocket);
WSACleanup();
return 1;
}
std::cout << "Echo Server started. Listening on port 8888..." << std::endl;
SOCKET ClientSocket;
while (true) {
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
std::cerr << "accept failed with error: " << WSAGetLastError() << std::endl;
continue;
}
std::cout << "Client connected." << std::endl;
char buffer[4096];
int recv_size;
while ((recv_size = recv(ClientSocket, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[recv_size] = '\0'; // Null-terminate the received data
std::cout << "Received: " << buffer << std::endl;
send(ClientSocket, buffer, recv_size, 0); // Echo data back
std::cout << "Echoed back: " << buffer << std::endl;
}
if (recv_size == 0) {
std::cout << "Client disconnected." << std::endl;
} else if (recv_size == SOCKET_ERROR) {
std::cerr << "recv failed with error: " << WSAGetLastError() << std::endl;
}
closesocket(ClientSocket);
}
closesocket(ListenSocket);
WSACleanup();
return 0;
}
README.md (Key Points)The README.md file typically contains instructions for building and running the sample. Key steps usually involve:
EchoClient.cpp or a telnet client) to connect to the server's IP address and port.EchoClient.cpp (Usage)A typical echo client will perform the following actions: