|
@@ -0,0 +1,81 @@
|
|
|
+const std = @import("std");
|
|
|
+const client = @import("client.zig");
|
|
|
+
|
|
|
+fn handle_connections(clients: *client.Clients) !void {
|
|
|
+ while (true) {
|
|
|
+ for (clients.clients.items) |c| {
|
|
|
+ clients.lock.lock();
|
|
|
+
|
|
|
+ var buf = [_]u8{0} ** 1024;
|
|
|
+ const sock = c.sock;
|
|
|
+ const r = std.posix.recv(sock, &buf, 0) catch |err| switch (err) {
|
|
|
+ error.WouldBlock => {
|
|
|
+ clients.lock.unlock();
|
|
|
+ continue;
|
|
|
+ },
|
|
|
+ else => {
|
|
|
+ std.debug.print("ERROR : {any}", .{err});
|
|
|
+ clients.lock.unlock();
|
|
|
+
|
|
|
+ continue;
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ if (r > 0) {
|
|
|
+ std.debug.print("Got {} bytes\n", .{r});
|
|
|
+ }
|
|
|
+
|
|
|
+ clients.lock.unlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ std.time.sleep(1_000_000 * 1000);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub fn main() !void {
|
|
|
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
|
+ defer _ = gpa.deinit();
|
|
|
+
|
|
|
+ const allocator = gpa.allocator();
|
|
|
+
|
|
|
+ const sock = try std.posix.socket(std.posix.AF.INET, std.posix.SOCK.STREAM, 0);
|
|
|
+ const parsed_address = try std.net.Address.parseIp4("127.0.0.1", 8080);
|
|
|
+ var sock_flags = try std.posix.fcntl(sock, std.c.F.GETFD, 0);
|
|
|
+ if (sock_flags < 0) {
|
|
|
+ std.debug.print("got incorrect flags");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const enable = [_]u8{ 1, 1, 1, 1, 1, 1, 1, 1 };
|
|
|
+
|
|
|
+ try std.posix.setsockopt(sock, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT | std.posix.SO.REUSEADDR, &enable);
|
|
|
+
|
|
|
+ sock_flags = sock_flags | std.c.SOCK.NONBLOCK;
|
|
|
+ const res = try std.posix.fcntl(sock, std.c.F.SETFD, sock_flags);
|
|
|
+ if (res < 0) {
|
|
|
+ std.debug.panic("could not fcntl\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Only allow ipv4. select parsed_address.any to allow ipv4 and ipv6 or in6 for only ipv6
|
|
|
+ try std.posix.bind(sock, @ptrCast(&parsed_address.in), parsed_address.getOsSockLen());
|
|
|
+ try std.posix.listen(sock, 5);
|
|
|
+
|
|
|
+ var addr: std.c.sockaddr.in = .{ .addr = 0, .port = 0 };
|
|
|
+ var addr_size: std.posix.socklen_t = @sizeOf(std.c.sockaddr.in);
|
|
|
+
|
|
|
+ var clients = client.Clients.init(allocator);
|
|
|
+ defer clients.deinit();
|
|
|
+
|
|
|
+ const t = try std.Thread.spawn(.{}, handle_connections, .{&clients});
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ // TODO: loop over this to accept more than one client
|
|
|
+ const sock2 = try std.posix.accept(sock, @ptrCast(&addr), &addr_size, std.posix.SOCK.NONBLOCK);
|
|
|
+
|
|
|
+ try clients.add(.{ .sock = sock2, .address = addr });
|
|
|
+
|
|
|
+ std.debug.print("Got client {any}\n", .{addr});
|
|
|
+ }
|
|
|
+
|
|
|
+ t.join();
|
|
|
+}
|