const std = @import("std"); pub fn main() !void { try run_server(4096, .{ 127, 0, 0, 1 }, 8888); } fn run_server( comptime BUFFER_SIZE: usize, host: [4]u8, port: u16, ) ServerError!void { const SOCK_DOMAIN = std.os.AF.INET; const SOCK_TYPE = std.os.SOCK.DGRAM; // Make socket descriptor. var sockfd = try std.os.socket(SOCK_DOMAIN, SOCK_TYPE, 0); defer std.os.closeSocket(sockfd); // Bind socket to address. const sockaddr = @bitCast(std.os.sockaddr, std.os.sockaddr.in{ .family = SOCK_DOMAIN, .port = std.mem.nativeToBig(u16, port), .addr = @bitCast(u32, host), // .zeros = ... }); try std.os.bind(sockfd, &sockaddr, @sizeOf(@TypeOf(sockaddr))); while (true) { std.debug.print("Waiting for message...\n", .{}); var buffer: [BUFFER_SIZE]u8 = undefined; var sockaddr_from: std.os.sockaddr = undefined; var sockaddr_from_len: u32 = @sizeOf(@TypeOf(sockaddr_from)); // Get message. const msg_len = try std.os.recvfrom( sockfd, &buffer, 0, &sockaddr_from, &sockaddr_from_len, ); std.debug.assert(sockaddr_from_len > 0); const socket_msg = buffer[0..msg_len]; std.debug.print(" Received message: {s}\n", .{socket_msg}); // Process message. for (socket_msg) |*char| { char.* = std.ascii.toUpper(char.*); } std.debug.print(" Sending response: {s}\n", .{socket_msg}); // Return response. _ = try std.os.sendto( sockfd, socket_msg, 0, &sockaddr_from, sockaddr_from_len, ); } } const ServerError = std.os.SocketError || std.os.BindError || std.os.RecvFromError || std.os.SendToError;