Description

This is a simple example of sockets programming in Win32 / C++ which is also a useful tool for debugging networking code and could also be used to diagnose certain network problems.

It is a simple console program which waits on a port for a connection and displays the incoming data. You can interact with that incoming connection just by typing or pasting into the console.

Usage

You could connect to it using a web browser, just set it listening on a port, for example 8080, and then browse to http://localhost:8080.

FakeServer running in a console window

You’ll see the browser’s query. Mine looks something like this:

GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

If you speak HTTP then you can reply and see the results in the web browser, for example you can paste this reply into the console:

HTTP/1.1 200 OK
Date: Thu, 28 Jan 2010 02:51:31 GMT
Server: FakeServer/0.2
Last-Modified: Thu, 07 Jan 2010 02:51:23 GMT
Accept-Ranges: bytes
Content-Length: 12
Content-Type: text/plain

Hello World!

Source Code

/*
  FakeServer.cpp

  Fake server
    Console app which listens on a port and when something
    connects you can talk to it.
    Simply waits for one connection and then goes into an infinite
    loop pumping data between the socket and the console.
*/


#include "stdafx.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <winsock.h>
#include <stdio.h>
#include <conio.h>



//---- Default listen port

int LISTEN_PORT = 8080;



//---- Data

WSADATA wi;
unsigned long thread_sock;
unsigned long thread_console;
sockaddr_in myaddr;
SOCKET sock;

SOCKET talk;



//---- run_sock

unsigned long __stdcall run_sock(void*)
{
  char buffer[256];
  int read;
  DWORD writ;

  int i;

  //  Read from socket and write to screen

  while( 0 < (read = recv( talk, buffer, 256, 0 )))
  {
    for( i=0; i<read; i++ ) printf("%c", buffer[i] );
  }

  return 0;
}



//---- run_console

unsigned long __stdcall run_console(void*)
{
  char buffer[256];
  DWORD read;
  DWORD writ;
  char c;

  while( c = getch() )
  {
    printf( "%c", c );
    send( talk, &c, 1, 0 );
  }

  return 0;
}



//---- main

int main( int argc, char* argv[] )
{
  //- Get command line argument (port to listen on)

  if( argc > 1 )
  {
    sscanf( argv[1], "%d", &LISTEN_PORT );
  }

  // Startup Winsock

  int err = WSAStartup(0x0101,&wi);

  printf("FakeServer v0.2\nStarted on port %d\n\n--\n", LISTEN_PORT );

  // Create a Socket and bind to a local port

  sock = socket(AF_INET,SOCK_STREAM,0);

  myaddr.sin_family = AF_INET;
  myaddr.sin_port = htons( LISTEN_PORT );
  myaddr.sin_addr.s_addr = INADDR_ANY;

  if( bind(sock,(sockaddr*)&myaddr,sizeof(sockaddr)))
  {
    printf( "ERROR: Could not bind to local port\r\n" );
    return 1;
  }

  // Listen for an incomming connection...

  int a = listen( sock, 1 );

  //  Wait for an incoming connection

  SOCKADDR_IN sa;
  talk = accept( sock, (LPSOCKADDR)&sa, NULL );

  //  Thread 1 - Reads from stdin, writes to dest socket

  CreateThread( NULL, 0, run_sock, NULL, 0, &thread_sock );

  //  Thread 2 - Reads from remote socket, writes to stdout

  CreateThread( NULL, 0, run_console, NULL, 0, &thread_console );

  //  infinte loop

  while( true )
  {
    Sleep( 1000 );
  }

  //  Cleanup the socket layer

  WSACleanup();

  return 0;
}

Source 5 files