From 1a505c032e3cf8ce67bd2478c236e81af591c181 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 25 Jun 2025 07:24:39 +0200 Subject: [PATCH] Unix sockets demo --- socket/Makefile | 19 +++++++++++++ socket/client.c | 41 +++++++++++++++++++++++++++ socket/server.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ socket/socket.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ socket/test.sh | 26 +++++++++++++++++ 5 files changed, 234 insertions(+) create mode 100644 socket/Makefile create mode 100644 socket/client.c create mode 100644 socket/server.c create mode 100644 socket/socket.c create mode 100644 socket/test.sh diff --git a/socket/Makefile b/socket/Makefile new file mode 100644 index 0000000..cd2294a --- /dev/null +++ b/socket/Makefile @@ -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 diff --git a/socket/client.c b/socket/client.c new file mode 100644 index 0000000..24d1249 --- /dev/null +++ b/socket/client.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/socket/server.c b/socket/server.c new file mode 100644 index 0000000..c5c7690 --- /dev/null +++ b/socket/server.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + +/* 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; +} diff --git a/socket/socket.c b/socket/socket.c new file mode 100644 index 0000000..0228b68 --- /dev/null +++ b/socket/socket.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/socket/test.sh b/socket/test.sh new file mode 100644 index 0000000..acb788e --- /dev/null +++ b/socket/test.sh @@ -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