#ifndef RCH_H
#define RCH_H
/*
welcome to ryans cute helpers (rch)
Ryan Alport, October 2025
this file provides implementations for a number of functions, each in the category of...
- windowing
- rendering
- clienting
- servering
this is by no means best practices but it is cool for a demo and getting started
*/
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
typedef SOCKET socket_t;
#include <windows.h>
typedef HANDLE thread_t;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef int socket_t;
#include <pthread.h>
typedef pthread_t thread_t;
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ----------------- cross-platform helpers -----------------
static void close_socket(socket_t sock) {
#ifdef _WIN32
closesocket(sock);
#else
close(sock);
#endif
}
static thread_t start_thread(void* (*func)(void*), void* arg) {
#ifdef _WIN32
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL);
#else
pthread_t tid;
pthread_create(&tid, NULL, func, arg);
return tid;
#endif
}
// ----------------- client networking -----------------
static socket_t client_start(const char* ip, int port) {
#ifdef _WIN32
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) return -1;
#endif
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) return -1;
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(ip);
if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
close_socket(sock);
return -1;
}
return sock;
}
static int client_send(socket_t sock, const void* buf, int len) {
return send(sock, buf, len, 0);
}
static int client_recv(socket_t sock, void* buf, int len) {
return recv(sock, buf, len, 0);
}
// ----------------- server networking -----------------
static socket_t server_start(int port) {
#ifdef _WIN32
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) return -1;
#endif
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) return -1;
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
close_socket(sock);
return -1;
}
if (listen(sock, 5) < 0) {
close_socket(sock);
return -1;
}
return sock;
}
static socket_t server_accept(socket_t server_sock) {
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
return accept(server_sock, (struct sockaddr*)&client_addr, &len);
}
static int server_send(socket_t client_sock, const void* buf, int len) {
return send(client_sock, buf, len, 0);
}
static int server_recv(socket_t client_sock, void* buf, int len) {
return recv(client_sock, buf, len, 0);
}
#endif