Learning Zig + Network stuff at the same time, and decided to try my hand at implementing a little local network chat server. While working through it, I ran into something that gave me a bit of trouble, and I’m sure there’s a better way to do it that I’ve not yet seen/figured out. Looking for someone to hopefully direct me to some resources that will help me on how to do this in a more “proper” way. Here’s how I currently have the server implemented -
const std = @import("std");
const net = std.net;
const posix = std.posix;
const print = std.debug.print;
pub fn main() !void {
const mimic_addr = try net.Address.parseIp4("127.0.0.1", 32100);
// socket boiler; specify attributes of the socket
const sock = try posix.socket(
posix.AF.INET,
posix.SOCK.DGRAM, // DGRAM signals UDP
posix.IPPROTO.UDP,
);
defer posix.close(sock);
// once you've got a socket built, bind it to a specific port;
// we defined the port above when parsing an IP4 address of localhost:32100
try posix.bind(sock, &mimic_addr.any, mimic_addr.getOsSockLen());
// Client info
var other_addr: posix.sockaddr align(4) = undefined;
var other_addrlen: posix.socklen_t = mimic_addr.getOsSockLen();
var buf: [1024]u8 = undefined;
print("Listening on {any}...\n", .{mimic_addr});
var running = true;
while (running) {
const n_recv = try posix.recvfrom(
sock,
buf[0..],
0,
&other_addr,
&other_addrlen,
);
const client_address: *align(4) const std.posix.sockaddr.in = @ptrCast(@alignCast(&other_addr));
print(
"received {d} byte(s) from {any};\n string: {s}\n",
.{ n_recv, @as([4]u8, @bitCast(client_address.addr)), buf[0..n_recv] },
);
const quit_cmd = "quit()";
const is_equal = std.mem.eql(u8, buf[0..6], quit_cmd);
if (is_equal) {
print("Received quit command. Exiting.\n", .{});
running = false;
} else {
const reply = buf[0..n_recv];
_ = try posix.sendto(
sock,
reply,
0,
&other_addr,
other_addrlen
);
print("Sent read receipt.\n", .{});
}
}
}
The piece I’m curious about is getting the client’s IP address from other_addr
after I call posix.recvfrom(...
Once the server receives a message from a client, as currently written, it prints the address as {127, 0, 0, 1}
. Ideally, I’d like it to print as 127.0.0.1
per the std.net.Address.format
definition, and avoid using align(4)
, @bitCast
, @as
, @ptrCast
, and @alignCast
in favor of a more elegant solution.
Like I said above, new to Zig (and honestly, new to lower-level languages in general) so there may be some basic concepts that I’m missing too - apologies and thanks in advance!