Skip to content

Instantly share code, notes, and snippets.

@jonahgeorge
Last active August 29, 2015 14:11
Show Gist options
  • Save jonahgeorge/0acc1ab7857a8ea933a2 to your computer and use it in GitHub Desktop.
Save jonahgeorge/0acc1ab7857a8ea933a2 to your computer and use it in GitHub Desktop.
Sample Programs using the Win32 API for CS344-001 Term Essay
/**
* Author: Jonah George
* Date: December 11, 2014
* Description: A simple echo server using the Winsock2 Api
* References: http://msdn.microsoft.com/en-us/library/windows/desktop/ms737593(v=vs.85).aspx
*/
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define BUFFER_LENGTH 512
#define PORT 4040
int main(int argc, char * argv[])
{
WSADATA data;
SOCKET ServerSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo * result = NULL;
struct addrinfo * ptr = NULL;
struct addrinfo hints;
char recv_str[BUFFER_LENGTH];
int ret;
// Initialize Winsock
ret = WSAStartup(MAKEWORD(2, 2), &data);
if (ret != 0)
{
printf("WSAStartup failed with error: %d\n", ret);
return 1;
}
// Win32 equivalent of memset(..., 0, ...);
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE; // Open a passive socket for listening
// Resolve the server address and port
// Binding to 0.0.0.0:8080 since NULL in server_name didn't work
ret = getaddrinfo("0.0.0.0", "8080", &hints, &result);
if (ret != 0)
{
printf("getaddrinfo failed with error: %d\n", GetLastError());
WSACleanup();
return 1;
}
// Create a socket for listening on the server
ServerSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ServerSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Bind the listening socket
ret = bind(ServerSocket, result->ai_addr, (int) result->ai_addrlen);
if (ret == SOCKET_ERROR)
{
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ServerSocket);
WSACleanup();
return 1;
}
// Free the addrinfo struct because we have active sockets
freeaddrinfo(result);
// Put server socket in listen mode
ret = listen(ServerSocket, SOMAXCONN);
if (ret == SOCKET_ERROR)
{
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ServerSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ServerSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ServerSocket);
ret = 0;
while (ret > 0)
{
ret = recv(ClientSocket, recv_str, BUFFER_LENGTH, 0);
// Valid message from client
if (ret > 0)
{
// Print client's messages
printf("Client sent: %s\n", recv_str);
// Echo the message back to the client
ret = send(ClientSocket, recv_str, ret, 0);
if (ret == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
// Client closed connection
else if (ret == 0)
{
printf("Connection closing...\n");
}
// Error handling if recv() failed
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
// Shutdown the client socket
ret = shutdown(ClientSocket, SD_SEND);
if (ret == SOCKET_ERROR)
{
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// Cleanup resources
closesocket(ClientSocket);
WSACleanup();
// Exit successfully
return 0;
}
/**
* Author: Jonah George
* Date: December 10, 2014
* Description: This file demonstrates basic usage of the Win32 file i/o commands.
*/
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#define BUFFERSIZE 1024
int main(int argc, char *argv[])
{
HANDLE file;
BOOL ret;
LPTSTR filename = _T("C:\\Users\\jonahgeorge\\Desktop\\test.txt");
char write_str[] = "Hello, world\n";
char recv_str[BUFFERSIZE];
// Open file for writing
// the CREATE_ALWAYS flag means that we will overwrite any pre-existing file
file = CreateFile(
filename,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
// Error handling if CreateFile() fails
if (file == INVALID_HANDLE_VALUE)
{
printf("Could not create file\n");
return 1;
}
// Write write_str to the file
ret = WriteFile(
file,
write_str,
strlen(write_str),
NULL,
NULL
);
// Error handling if WriteFile() fails
if (ret == FALSE)
{
printf("Could not write file\n");
return 1;
}
// Read file into recv_str
ret = ReadFile(
file,
recv_str,
BUFFERSIZE - 1,
NULL,
NULL
);
// Error handling if ReadFile() fails
if (ret == FALSE)
{
DWORD error = GetLastError();
if (error == ERROR_IO_PENDING)
printf("Read operating is pending asynchronous operation\n");
else
printf("Could not read file\n");
return 1;
}
else
{
printf("Contents: %s\n", recv_str);
}
// Close the file handle
CloseHandle(file);
// Exit successfully
return 0;
}
/**
* Author: Jonah George
* Date: December 11, 2014
* Description: This file demonstrates basic usage of the Win32 thread functions.
* By creating 50 threads, simulating work on each thread and then waiting
* for the threads to return.
*/
// Required for rand_s()
#define _CRT_RAND_S
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define MAX_THREADS 50
// Function for each thread to run
// Simulates "work"
void * run_thread(void * ptr)
{
int work_duration;
unsigned int number;
// Get the id for the current thread to use as an identifier
DWORD id = GetCurrentThreadId();
printf("#%d: Generating work\n", id);
// Thread-safe randon number generator
rand_s(&number);
work_duration = number % 1000;
printf("#%d: Working for %d milliseconds\n", id, work_duration);
// Sleep for x milliseconds
Sleep(work_duration);
printf("#%d: Finished work\n", id);
return NULL;
}
int main(int argc, char * argv[])
{
HANDLE threads[MAX_THREADS];
int i;
// Create threads
for (i = 0; i < MAX_THREADS; i++)
{
threads[i] = CreateThread(
NULL, // Thread handle CANNOT be inherited by child processes
0, // Use default stack size
(void *) run_thread, // Pointer to the function to be run by thread
NULL, // Parameters for function
0, // Thread runs immediately after creation
NULL // Do not return thread identifier
);
// Error handling if CreateThread() fails
if (threads[i] == NULL)
{
printf("CreateThread() failed\n");
return 1;
}
}
// Wait for each thread
for (i = 0; i < MAX_THREADS; i++)
{
WaitForSingleObject(threads[i], INFINITE);
}
// Exit successfully
return 0;
}