From 311dc687af19147a9fc9c7bf315eef769fc36cae Mon Sep 17 00:00:00 2001 From: Travis Avey Date: Tue, 2 Jun 2026 08:52:15 -0400 Subject: [PATCH] updates for 2nd video --- client/.gitignore | 2 + LICENSE => client/LICENSE | 0 build/.gitkeep => client/README.md | 0 {docs => client/docs}/.gitkeep | 0 {lib => client/lib}/.gitkeep | 0 project.json => client/project.json | 2 +- {resources => client/resources}/.gitkeep | 0 {scripts => client/scripts}/.gitkeep | 0 {src => client/src}/.gitkeep | 0 client/src/client.c3 | 29 +++++++ client/src/main.c3 | 21 ++++++ {test => client/test}/.gitkeep | 0 server/.gitignore | 2 + server/LICENSE | 0 server/README.md | 0 server/docs/.gitkeep | 0 server/lib/.gitkeep | 0 server/project.json | 45 +++++++++++ server/resources/.gitkeep | 0 server/scripts/.gitkeep | 0 server/src/.gitkeep | 0 server/src/main.c3 | 14 ++++ server/src/server.c3 | 96 ++++++++++++++++++++++++ server/test/.gitkeep | 0 src/main.c3 | 61 --------------- 25 files changed, 210 insertions(+), 62 deletions(-) create mode 100644 client/.gitignore rename LICENSE => client/LICENSE (100%) rename build/.gitkeep => client/README.md (100%) rename {docs => client/docs}/.gitkeep (100%) rename {lib => client/lib}/.gitkeep (100%) rename project.json => client/project.json (98%) rename {resources => client/resources}/.gitkeep (100%) rename {scripts => client/scripts}/.gitkeep (100%) rename {src => client/src}/.gitkeep (100%) create mode 100644 client/src/client.c3 create mode 100644 client/src/main.c3 rename {test => client/test}/.gitkeep (100%) create mode 100644 server/.gitignore create mode 100644 server/LICENSE create mode 100644 server/README.md create mode 100644 server/docs/.gitkeep create mode 100644 server/lib/.gitkeep create mode 100644 server/project.json create mode 100644 server/resources/.gitkeep create mode 100644 server/scripts/.gitkeep create mode 100644 server/src/.gitkeep create mode 100644 server/src/main.c3 create mode 100644 server/src/server.c3 create mode 100644 server/test/.gitkeep delete mode 100644 src/main.c3 diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..3c0160d --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,2 @@ +build/ +out/ diff --git a/LICENSE b/client/LICENSE similarity index 100% rename from LICENSE rename to client/LICENSE diff --git a/build/.gitkeep b/client/README.md similarity index 100% rename from build/.gitkeep rename to client/README.md diff --git a/docs/.gitkeep b/client/docs/.gitkeep similarity index 100% rename from docs/.gitkeep rename to client/docs/.gitkeep diff --git a/lib/.gitkeep b/client/lib/.gitkeep similarity index 100% rename from lib/.gitkeep rename to client/lib/.gitkeep diff --git a/project.json b/client/project.json similarity index 98% rename from project.json rename to client/project.json index 3501872..ec8ef2a 100644 --- a/project.json +++ b/client/project.json @@ -29,7 +29,7 @@ // "target": "windows-x64", // Targets. "targets": { - "c3hat": { + "client": { // Executable or library. "type": "executable", // Additional libraries, sources diff --git a/resources/.gitkeep b/client/resources/.gitkeep similarity index 100% rename from resources/.gitkeep rename to client/resources/.gitkeep diff --git a/scripts/.gitkeep b/client/scripts/.gitkeep similarity index 100% rename from scripts/.gitkeep rename to client/scripts/.gitkeep diff --git a/src/.gitkeep b/client/src/.gitkeep similarity index 100% rename from src/.gitkeep rename to client/src/.gitkeep diff --git a/client/src/client.c3 b/client/src/client.c3 new file mode 100644 index 0000000..91e2a0f --- /dev/null +++ b/client/src/client.c3 @@ -0,0 +1,29 @@ +module client; +import std::net; +import std::io; + +const uint BUFFER_SIZE = 4096; + +fn void? sendMsg(String url, uint port, String msg) { + TcpSocket socket = tcp::connect(url, port)!; + + int pos = 0; + while (try sent = socket.write(msg[pos:msg.len])) { + + if (sent == 0) break; + + pos += (int)sent; + + if (sent >= msg.len) break; + } + + char[BUFFER_SIZE] buffer; + usz recv = socket.read(&buffer)!; + + io::printfn("%s", (String)buffer[:recv]); +} + + + + + diff --git a/client/src/main.c3 b/client/src/main.c3 new file mode 100644 index 0000000..ab4621c --- /dev/null +++ b/client/src/main.c3 @@ -0,0 +1,21 @@ +module client; +import std::io; + +fn int main(String[] args) { + if (args.len < 4) { + io::printn("error: not enough arguments"); + io::printfn("usage: %s ", args[0]); + return -1; + } + String host = args[1]; + uint? port = args[2].to_uint(); + if (catch err = port) { + io::printfn("couldn't convert %s to a port", args[2]); + return -1; + } + String msg = args[3]; + + sendMsg(host, port, msg)!!; + + return 0; +} diff --git a/test/.gitkeep b/client/test/.gitkeep similarity index 100% rename from test/.gitkeep rename to client/test/.gitkeep diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..3c0160d --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,2 @@ +build/ +out/ diff --git a/server/LICENSE b/server/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/server/README.md b/server/README.md new file mode 100644 index 0000000..e69de29 diff --git a/server/docs/.gitkeep b/server/docs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/server/lib/.gitkeep b/server/lib/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/server/project.json b/server/project.json new file mode 100644 index 0000000..4f7b51d --- /dev/null +++ b/server/project.json @@ -0,0 +1,45 @@ +{ + // Language version of C3. + "langrev": "1", + // Warnings used for all targets. + "warnings": [ "no-unused" ], + // Directories where C3 library files may be found. + "dependency-search-paths": [ "lib" ], + // Libraries to use for all targets. + "dependencies": [ ], + // Authors, optionally with email. + "authors": [ "John Doe " ], + // Version using semantic versioning. + "version": "0.1.0", + // Sources compiled for all targets. + "sources": [ "src/**" ], + // Test sources compiled for all targets. + "test-sources": [ "test/**" ], + // C sources if the project also compiles C sources + // relative to the project file. + // "c-sources": [ "csource/**" ], + // Include directories for C sources relative to the project file. + // "c-include-dirs": [ "csource/include" ], + // Build location, relative to project file. + "build-dir": "build", + // Output location, relative to project file. + "output": "build", + // Architecture and OS target. + // You can use 'c3c --list-targets' to list all valid targets. + // "target": "windows-x64", + // Targets. + "targets": { + "server": { + // Executable or library. + "type": "executable", + // Additional libraries, sources + // and overrides of global settings here. + }, + }, + // Global settings. + // CPU name, used for optimizations in the LLVM backend. + "cpu": "generic", + // Optimization: "O0", "O1", "O2", "O3", "O4", "O5", "Os", "Oz". + "opt": "O0" + // See resources/examples/project_all_settings.json and 'c3c --list-project-properties' to see more properties. +} \ No newline at end of file diff --git a/server/resources/.gitkeep b/server/resources/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/server/scripts/.gitkeep b/server/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/server/src/.gitkeep b/server/src/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/server/src/main.c3 b/server/src/main.c3 new file mode 100644 index 0000000..48acaad --- /dev/null +++ b/server/src/main.c3 @@ -0,0 +1,14 @@ +module server; +import std::io; +import std::net; +import std::collections; + +fn int main(String[] args) { + String host = "localhost"; + uint port = 9500; + uint backlog = 100; + + startServer(host, port, backlog)!!; + + return 0; +} diff --git a/server/src/server.c3 b/server/src/server.c3 new file mode 100644 index 0000000..81f6a08 --- /dev/null +++ b/server/src/server.c3 @@ -0,0 +1,96 @@ +module server; +import std::io; +import std::net; +import std::collections; +import std::thread::pool; + +const int BUFFSIZE = 4096; +const int THREAD_COUNT = 100; + +fn void? startServer(String host, uint port, uint backlog=20) { + bool shouldQuit = false; + + TcpServerSocket? server = tcp::listen( + host, port, backlog, + SocketOption.REUSEADDR, + ip_protocol: IpProtocol.IPV4); + + if (catch err = server) { + io::printfn("unable to create server socket %s", err); + return; + } + + defer { + if (catch err = server.close()) { + io::printfn("error closing socket %s", err); + } + } + ThreadPool{THREAD_COUNT} workerPool; + if (catch err = workerPool.init()) { + io::printfn("error setting up thread pool: %s", err); + return; + } + + while (!shouldQuit) { + TcpSocket? client = tcp::accept(&server); + if (catch err = client) { + io::printfn("error accepting client %s", err); + continue; + } + //readInput(&client); + workerPool.push(&handleThread, &client); + } + +} + +fn int handleThread(void *args) => @pool_init(mem, 65536) { + TcpSocket *client = (TcpSocket*)args; + readInput(client); + return 0; +} + +fn void readInput(TcpSocket *client) { + defer (void)client.close(); + char[BUFFSIZE] buffer; + + List{String} data; + data.init(mem); + while (try usz read = client.read(&buffer)) { + data.push((String)buffer[:read]); + if (read < BUFFSIZE) { + break; + } + } + processInput(&data); + broadcast(client, &data); +} + +fn void processInput(List{String} *input) { + foreach (item : input) { + io::printfn("%s", item); + } +} + +fn void broadcast(TcpSocket *socket, List{String} *messages) { + + foreach (msg : messages) { + + int pos = 0; + + while (try usz sent = socket.write(msg[pos:msg.len])) { + + if (sent == 0) break; + + pos += (uint)sent; + + if (pos >= msg.len) break; + } + } +} + + + + + + + diff --git a/server/test/.gitkeep b/server/test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main.c3 b/src/main.c3 deleted file mode 100644 index c356b16..0000000 --- a/src/main.c3 +++ /dev/null @@ -1,61 +0,0 @@ -module c3hat; -import std::io; -import std::net; -import std::collections; - -fn int main(String[] args) { - String host = "localhost"; - uint port = 9500; - uint backlog = 100; - bool shouldQuit = false; - const int BUFFSIZE = 4096; - - TcpServerSocket? server = tcp::listen( - host, port, backlog, - SocketOption.REUSEADDR, - ip_protocol: IpProtocol.IPV4); - - if (catch err = server) { - io::printfn("unable to create server socket %s", err); - return -1; - } - - defer { - if (catch err = server.close()) { - io::printfn("error closing socket %s", err); - } - } - - while (!shouldQuit) { - TcpSocket? client = tcp::accept(&server); - if (catch err = client) { - io::printfn("error accepting client %s", err); - continue; - } - defer { - if (catch err = client.close()) { - io::printfn("error closing client socket %s", err); - } - } - char[BUFFSIZE] buffer; - - List{String} data; - data.init(mem); - while (try usz read = client.read(&buffer)) { - //io::printfn("buffer %s", (String)buffer[:read]); - data.push((String)buffer[:read]); - if (read < BUFFSIZE) { - break; - } - } - - foreach (item : data) { - io::printfn("%s", item); - if (item.contains("quit")) { - shouldQuit = true; - } - } - } - - return 0; -}