Last active
August 29, 2015 14:11
-
-
Save jonahgeorge/0acc1ab7857a8ea933a2 to your computer and use it in GitHub Desktop.
Sample Programs using the Win32 API for CS344-001 Term Essay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c
http://msdn.microsoft.com/en-us/library/esszf9hw.aspx