Compare commits

..

2 commits

Author SHA1 Message Date
Imbus
196358c49f Murmur3 2025-06-25 07:25:00 +02:00
Imbus
1a505c032e Unix sockets demo 2025-06-25 07:24:39 +02:00
6 changed files with 280 additions and 0 deletions

46
murmur3.c Normal file
View file

@ -0,0 +1,46 @@
#include <stdint.h>
#include <stdio.h>
uint32_t murmur3_32(const uint8_t* key, size_t len, uint32_t seed) {
uint32_t h = seed;
uint32_t c1 = 0xcc9e2d51;
uint32_t c2 = 0x1b873593;
uint32_t k;
size_t i;
for (i = 0; i + 4 <= len; i += 4) {
k = *(uint32_t*)(key + i);
k *= c1;
k = (k << 15) | (k >> (32 - 15));
k *= c2;
h ^= k;
h = (h << 13) | (h >> (32 - 13));
h = h * 5 + 0xe6546b64;
}
// Tail handling
k = 0;
switch (len & 3) {
case 3: k ^= key[i + 2] << 16;
case 2: k ^= key[i + 1] << 8;
case 1: k ^= key[i + 0];
k *= c1; k = (k << 15) | (k >> (32 - 15)); k *= c2; h ^= k;
}
h ^= len;
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
int main() {
const char *key = "hello world";
uint32_t hash = murmur3_32((const uint8_t *)key, 11, 42); // seed = 42
printf("MurmurHash3 of \"%s\" is 0x%X\n", key, hash);
return 0;
}

19
socket/Makefile Normal file
View file

@ -0,0 +1,19 @@
CC ?= gcc
CFLAGS ?= -Wall -g
all: server.elf client.elf
server.elf: server.c
client.elf: client.c
%.elf: %.c
@echo CC $@
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test: all
bash test.sh
clean:
rm -f *.elf *.o
.PHONY: test clean

41
socket/client.c Normal file
View file

@ -0,0 +1,41 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SOCKET_PATH "/tmp/demosocket"
int main() {
int sock_fd;
struct sockaddr_un addr;
char buffer[100];
sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) <
0) {
perror("connect");
exit(EXIT_FAILURE);
}
send(sock_fd, "ping\n", 4, 0);
int bytes = recv(sock_fd, buffer, sizeof(buffer) - 1, 0);
if (bytes > 0) {
buffer[bytes] = '\0';
printf("Client got: %s\n", buffer);
}
close(sock_fd);
return 0;
}

75
socket/server.c Normal file
View file

@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
/* Unix sockets need a path */
#define SOCK_PATH "/tmp/demosocket"
#define BUF_SIZE 128
char buf[BUF_SIZE];
int main(void) {
struct sockaddr_un addr;
int server_fd, client_fd;
char *msg = "Hello\n";
memcpy(buf, msg, strlen(msg));
// Unlink this in case its still around
unlink(SOCK_PATH);
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("Error: Could not open socket...\n");
exit(EXIT_FAILURE);
}
// Wipe this for security
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", SOCK_PATH);
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("Could not bind server...\n");
close(server_fd);
exit(EXIT_FAILURE);
}
if (listen(server_fd, 1) == -1) {
perror("Listen");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server listening on %s...\n", SOCK_PATH);
while (1) {
// This will block until a message is recieved
client_fd = accept(server_fd, NULL, NULL);
if (client_fd == -1) {
perror("accept");
close(server_fd);
exit(EXIT_FAILURE);
}
ssize_t received = recv(client_fd, buf, BUF_SIZE - 1, 0);
if (received > 0) {
buf[received] = '\0';
printf("Server got: %s\n", buf);
// Send a reply
const char *reply = "pong!\n";
send(client_fd, reply, strlen(reply), 0);
} else {
perror("recv");
}
}
close(client_fd);
close(server_fd);
unlink(SOCK_PATH);
return 0;
}

73
socket/socket.c Normal file
View file

@ -0,0 +1,73 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/demosocket"
#define BUF_SIZE 128
int main(void) {
int server_fd, client_fd;
struct sockaddr_un addr;
char buf[BUF_SIZE];
// Clean up any leftover socket file
unlink(SOCKET_PATH);
// Create socket
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// Zero out and set up the address structure
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
// Bind the socket to the path
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind");
close(server_fd);
exit(EXIT_FAILURE);
}
// Listen for a connection
if (listen(server_fd, 1) == -1) {
perror("listen");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server listening on %s...\n", SOCKET_PATH);
// Accept a connection
client_fd = accept(server_fd, NULL, NULL);
if (client_fd == -1) {
perror("accept");
close(server_fd);
exit(EXIT_FAILURE);
}
// Receive a message
ssize_t received = recv(client_fd, buf, BUF_SIZE - 1, 0);
if (received > 0) {
buf[received] = '\0';
printf("Received: %s", buf);
// Send a reply
const char *reply = "Got your message!\n";
send(client_fd, reply, strlen(reply), 0);
} else {
perror("recv");
}
// Clean up
close(client_fd);
close(server_fd);
unlink(SOCKET_PATH);
return 0;
}

26
socket/test.sh Normal file
View file

@ -0,0 +1,26 @@
#!/bin/bash
SOCKET_PATH="/tmp/demosocket"
# Cleanup function to be run on exit
cleanup() {
echo "Cleaning up..."
if [[ -n "$SERVER_PID" ]]; then
kill "$SERVER_PID" 2>/dev/null || true
wait "$SERVER_PID" 2>/dev/null || true
fi
rm -f "$SOCKET_PATH"
}
# Trap EXIT to ensure cleanup runs
trap cleanup EXIT
echo "Starting server..."
./server.elf &
SERVER_PID=$!
# Wait briefly for the server to start
sleep 0.2
echo "Running client..."
./client.elf