Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "mswsock.lib")
#pragma comment (lib, "advapi32.lib")
fd_set fds_dup(fd_set* src)
{
unsigned i;
fd_set src_copy;
FD_ZERO(&src_copy);
src_copy.fd_count = src->fd_count;
for (i = 0; i < src_copy.fd_count; ++i)
src_copy.fd_array[i] = src->fd_array[i];
return src_copy;
}
int main()
{
WSADATA wsaData;
SOCKET server_sock;
const char* server_address_s = "localhost";
const char* PORT = "7000";
struct addrinfo* server_address;
BOOL opt_val = FALSE;
const unsigned int PENDING_SIZE = 5;
fd_set read_fds;
struct addrinfo hint;
const struct timeval timeout = {1, 0};
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
fprintf(stderr, "main(): error calling 'WSAStartup()'");
WSACleanup();
exit(EXIT_FAILURE);
}
hint.ai_family = 0;
hint.ai_socktype = SOCK_STREAM;
hint.ai_flags = AI_PASSIVE;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
if (getaddrinfo(server_address_s, PORT, &hint, &server_address) != 0)
{
printf("main(): cannot locate host, error code=%ld, exiting program\n", WSAGetLastError());
WSACleanup();
exit(EXIT_FAILURE);
}
server_sock = socket(server_address->ai_family, server_address->ai_socktype, server_address->ai_protocol);
if (server_sock == INVALID_SOCKET)
{
fprintf(stderr, "main(): cannot create socket, error code=%ld, exiting program\n", WSAGetLastError());
WSACleanup();
exit(EXIT_FAILURE);
}
setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt_val, sizeof(int));
if (bind(server_sock, server_address->ai_addr, server_address->ai_addrlen) == SOCKET_ERROR)
{
printf("main(): cannot bind, error code=%ld, exiting program\n", WSAGetLastError());
WSACleanup();
exit(EXIT_FAILURE);
}
freeaddrinfo(server_address);
if (listen(server_sock, PENDING_SIZE) == SOCKET_ERROR)
{
printf("main(): cannot listen, error code=%ld, exiting program\n", WSAGetLastError());
WSACleanup();
exit(EXIT_FAILURE);
}
FD_ZERO(&read_fds);
FD_SET(server_sock, &read_fds);
while (1)
{
unsigned i;
int nfds;
fd_set read_fds_copy;
FD_ZERO(&read_fds_copy);
read_fds_copy = fds_dup(&read_fds);
printf("main(): while...\n");
nfds = select(0, &read_fds_copy, NULL, NULL, NULL);
if (nfds == SOCKET_ERROR)
{
printf("main(): error calling 'select()', exiting program\n");
WSACleanup();
exit(EXIT_FAILURE);
}
else if (nfds == 0)
{
printf("main(): select time limit expired\n");
continue;
}
for (i = 0; i < read_fds_copy.fd_count; ++i)
{
SOCKET sock = read_fds_copy.fd_array[i];
if (sock == server_sock)
{
// new client accepted
struct sockaddr_in client_address;
socklen_t client_address_len = sizeof(struct sockaddr);
SOCKET client_sock;
char addr_buf[1000];
const char* client_address_s;
client_sock = accept(server_sock, (struct sockaddr*)&client_address, &client_address_len);
//client_sock = accept(server_sock, NULL, NULL);
if (client_sock == INVALID_SOCKET)
{
printf("main(): cannot accept client, error code=%ld, sleeping\n", WSAGetLastError());
Sleep(1000);
continue;
}
printf("main(): client accepted...\n");
client_address_s = inet_ntop(AF_INET, &client_address, addr_buf, INET_ADDRSTRLEN);
if (client_address_s == NULL)
printf("main(): cannot read client address\n");
else
printf("main(): client accepted from %s\n", client_address_s);
FD_SET(client_sock, &read_fds);
}
else
{
// client request
const int REQUEST_LEN = 1000;
char request[1000];
int result;
memset(request, '\0', REQUEST_LEN);
result = recv(sock, request, REQUEST_LEN, 0);
if (result == SOCKET_ERROR)
{
// no request from client
printf("main(): cannot receive request\n");
closesocket(sock);
FD_CLR(sock, &read_fds);
continue;
}
else if (result == 0)
{
// client closed
printf("main(): client closed\n");
closesocket(sock);
FD_CLR(sock, &read_fds);
continue;
}
else
{
// echo client's request
printf("main(): request=%s\n", request);
result = send(sock, request, strlen(request), 0);
if (result == SOCKET_ERROR)
{
fprintf(stderr, "main(): cannot send response\n");
closesocket(sock);
FD_CLR(sock, &read_fds);
continue;
}
printf("main(): echo sent\n");
}
}
}
}
WSACleanup();
return EXIT_SUCCESS;
}
If I put a line