#include <stdio.h> #include <winsock2.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 256 #define die(...) do { fprintf(stderr, __VA_ARGS__); WSACleanup(); exit(1); } while(0) #define debug(...) do { fprintf(stderr, __VA_ARGS__); } while(0) static void wsa_startup(WORD version, WSADATA *wsaData) { int n; if ((n = WSAStartup(version, wsaData)) != 0) { die("WASStartup(): %d\n", n); } if (version != wsaData->wVersion) { die("WASStartup(): WinSock version %d.%d not supported\n", LOWORD(version), HIWORD(version)); } } void echo(SOCKET sock) { while (1) { char buf[RCVBUFSIZE + 1]; size_t len; if ((len = recv(sock, buf, RCVBUFSIZE, 0)) < 0) { die("recv(): %d\n", WSAGetLastError()); } if (len == 0) { break; } buf[len] = '\0'; debug("recv: %s", buf); if (send(sock, buf, len, 0) < 0) { die("send(): %d\n", WSAGetLastError()); } } closesocket(sock); } int main() { WSADATA wsaData; SOCKET sock, s; struct sockaddr_in addr, caddr; int len; wsa_startup(MAKEWORD(2, 0), &wsaData); if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { die("socket(): %d\n", WSAGetLastError()); } addr.sin_family = AF_INET; addr.sin_port = htons(ECHO_PORT); addr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) { die("bind(): %d\n", WSAGetLastError()); } if (listen(sock, MAX_BACKLOG) != 0) { die("listen(): %d\n", WSAGetLastError()); } while(1) { len = sizeof(caddr); if ((s = accept(sock, (struct sockaddr *) &caddr, &len)) == INVALID_SOCKET) { die("accepr(): %d\n", WSAGetLastError()); } debug("accepted.\n"); echo(s); debug("closed.\n"); } WSACleanup(); return 0; }