Skip to content

Instantly share code, notes, and snippets.

@dmitryvk
Created July 16, 2010 16:51
Show Gist options
  • Save dmitryvk/478619 to your computer and use it in GitHub Desktop.
Save dmitryvk/478619 to your computer and use it in GitHub Desktop.
//Built with `g++-3 -Wall -g -O2 -o test-sockets.exe -mno-cygwin test-sockets.cpp -l ws2_32`
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Winsock2.h>
#include <stdio.h>
#include <stdlib.h>
void init()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
exit(1);
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
fprintf(stderr, "Could not find a usable version of Winsock.dll\n");
WSACleanup();
exit(1);
}
else
fprintf(stderr, "The Winsock 2.2 dll was found okay\n");
}
int port;
HANDLE thread_listener, thread_writer;
DWORD WINAPI listener(LPVOID parm)
{
HANDLE socket = (HANDLE)parm;
char buf[4096];
unsigned long read_bytes;
fprintf(stderr, "listener: listening\n");
fflush(stderr);
while (ReadFile(socket, &buf[0], 4096, &read_bytes, NULL) && read_bytes > 0) {
fprintf(stderr, "listener: received %d bytes: %s\n", read_bytes, buf);
fflush(stderr);
Sleep(1000);
}
fprintf(stderr, "listener: exiting\n");
fflush(stderr);
return 0;
}
DWORD WINAPI writer(LPVOID parm)
{
HANDLE socket = (HANDLE)parm;
fprintf(stderr, "writer: writing\n");
fflush(stderr);
char buf[1] = { '.' };
unsigned long wrote_bytes;
while (true) {
Sleep(100);
fprintf(stderr, "writer: doing a write\n");
fflush(stderr);
if (!WriteFile(socket, &buf[0], sizeof(buf), &wrote_bytes, NULL) || wrote_bytes == 0) break;
fprintf(stderr, "writer: done writing\n");
fflush(stderr);
}
fprintf(stderr, "writer: done writing\n");
fflush(stderr);
return 0;
}
void wait_for_connection()
{
HANDLE socket = (HANDLE)WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
fprintf(stderr, "socket = 0x%p\n", socket);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(port);
if (bind((SOCKET)socket, (struct sockaddr*) &addr, sizeof(addr)) == SOCKET_ERROR) {
fprintf(stderr, "bind failed, %d\n", WSAGetLastError());
exit(1);
}
if (listen((SOCKET)socket, 5) == SOCKET_ERROR) {
fprintf(stderr, "listen failed, %d\n", WSAGetLastError());
exit(1);
}
fflush(stderr);
HANDLE accepted = (HANDLE)WSAAccept((SOCKET)socket, NULL, NULL, NULL, 0);
fprintf(stderr, "accepted = 0x%p\n", accepted);
if (accepted == (HANDLE)INVALID_SOCKET) {
fprintf(stderr, "WSAGetLastError() == %d\n", WSAGetLastError());
exit(1);
}
thread_listener = CreateThread(NULL, 0, &listener, (LPVOID)accepted, 0, NULL);
thread_writer = CreateThread(NULL, 0, writer, (LPVOID)accepted, 0, NULL);
}
void wait_for_threads()
{
WaitForSingleObject(thread_listener, INFINITE);
WaitForSingleObject(thread_writer, INFINITE);
}
int main(int argc, char * argv[])
{
if (argc != 2) {
fprintf(stderr, "argc != 2\n");
exit(1);
}
if (sscanf(argv[1], "%d", &port) != 1) {
fprintf(stderr, "sscanf(...) != 1\n");
exit(1);
}
fprintf(stderr, "starting in at port %d\n", port);
init();
wait_for_connection();
wait_for_threads();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment