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(7 * std.time.ns_per_ms); } } 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}); std.time.sleep(16 * std.time.ns_per_ms); } t.join(); }