WinSock API Reference Examples
Explore practical code samples demonstrating the use of the Windows Sockets API (WinSock) for network programming. These examples cover common scenarios like creating TCP/IP clients and servers, UDP communication, and handling socket events.
1. Basic TCP Server Example
A simple TCP server that listens for incoming connections and echoes received data back to the client.
// Winsock2.h, Winsock.h, Ws2tcpip.h, windows.h required
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int main() {
WSADATA wsaData;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct sockaddr_in serverAddr, clientAddr;
int clientAddrSize = sizeof(clientAddr);
char buffer[512];
int bytesReceived;
// Create a SOCKET for the server to listen for client connections
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Setup the TCP listening socket
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(8080);
// Bind the socket
iResult = bind(ListenSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Listen on the socket
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Server listening on port 8080...\n");
// Accept a client socket
ClientSocket = accept(ListenSocket, (struct sockaddr *) &clientAddr, &clientAddrSize);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the client disconnects
do {
bytesReceived = recv(ClientSocket, buffer, sizeof(buffer) - 1, 0);
if (bytesReceived > 0) {
buffer[bytesReceived] = '\0'; // Null-terminate the received data
printf("Bytes received: %d\n", bytesReceived);
printf("Received: %s\n", buffer);
// Echo the buffer back to the sender
iResult = send(ClientSocket, buffer, bytesReceived, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
break;
}
} else if (bytesReceived == 0) {
printf("Connection closing...\n");
} else {
printf("recv failed: %d\n", WSAGetLastError());
break;
}
} while (bytesReceived > 0);
// shutdown the send half of the connection
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
2. Basic TCP Client Example
A simple TCP client that connects to a server and sends a message, then receives and prints the echoed response.
// Winsock2.h, Ws2tcpip.h, windows.h required
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int main( int argc, char **argv ) {
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in serverAddr;
int iResult;
char recvBuf[512];
int recvBytes;
// Validate command line arguments
if (argc != 3) {
printf("usage: %s <server_ip> <port>\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup( MAKEWORD(2, 2), &wsaData );
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
// Create a SOCKET for connecting to server
ConnectSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// Setup the server address
//----------------------
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons( (unsigned short) atoi(argv[2]) );
inet_pton(AF_INET, argv[1], &serverAddr.sin_addr);
// Connect to server.
iResult = connect( ConnectSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr) );
if (iResult == SOCKET_ERROR) {
printf("connect failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Send an initial message to the server
const char* sendThis = "Hello from WinSock client!";
iResult = send( ConnectSocket, sendThis, (int)strlen(sendThis), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the server closes the connection
do {
recvBytes = recv(ConnectSocket, recvBuf, sizeof(recvBuf) - 1, 0);
if (recvBytes > 0) {
recvBuf[recvBytes] = '\0';
printf("Bytes received: %d\n", recvBytes);
printf("Received: %s\n", recvBuf);
} else if (recvBytes == 0) {
printf("Connection closing...\n");
} else {
printf("recv failed: %d\n", WSAGetLastError());
}
} while( recvBytes > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
3. UDP Echo Client/Server Pair
A pair of UDP programs demonstrating sending and receiving datagrams. The server simply echoes back any datagrams it receives.
// UDP Server Side
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main_udp_server() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in serverAddr, clientAddr;
char buffer[512];
int serverAddrSize = sizeof(serverAddr);
int clientAddrSize = sizeof(clientAddr);
int bytesReceived;
WSAStartup(MAKEWORD(2, 2), &wsaData);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(9090);
serverAddr.sin_addr.s_addr = INADDR_ANY;
bind(sock, (struct sockaddr *) &serverAddr, serverAddrSize);
printf("UDP Server listening on port 9090...\n");
while(true) {
bytesReceived = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&clientAddr, &clientAddrSize);
if (bytesReceived > 0) {
buffer[bytesReceived] = '\0';
printf("Received from %s:%d: %s\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port), buffer);
sendto(sock, buffer, bytesReceived, 0, (struct sockaddr *)&clientAddr, clientAddrSize);
}
}
closesocket(sock);
WSACleanup();
return 0;
}
// UDP Client Side
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main_udp_client( int argc, char **argv ) {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in serverAddr;
char buffer[512];
int serverAddrSize = sizeof(serverAddr);
int bytesReceived;
if (argc != 3) {
printf("usage: %s <server_ip> <message>\n", argv[0]);
return 1;
}
WSAStartup(MAKEWORD(2, 2), &wsaData);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(9090);
inet_pton(AF_INET, argv[1], &serverAddr.sin_addr);
sendto(sock, argv[2], (int)strlen(argv[2]), 0, (struct sockaddr *)&serverAddr, serverAddrSize);
printf("Sent: %s\n", argv[2]);
bytesReceived = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&serverAddr, &serverAddrSize);
if (bytesReceived > 0) {
buffer[bytesReceived] = '\0';
printf("Received: %s\n", buffer);
}
closesocket(sock);
WSACleanup();
return 0;
}