Skip to content

Instantly share code, notes, and snippets.

@newmedia2
Forked from andrewrk/basic-tcp-chat.zig
Created October 21, 2023 15:03
Show Gist options
  • Select an option

  • Save newmedia2/e4e6bcd6c81c162c8ccd90e42b703d15 to your computer and use it in GitHub Desktop.

Select an option

Save newmedia2/e4e6bcd6c81c162c8ccd90e42b703d15 to your computer and use it in GitHub Desktop.
const std = @import("std");
const net = std.net;
const fs = std.fs;
const os = std.os;
pub const io_mode = .evented;
pub fn main() anyerror!void {
const allocator = std.heap.page_allocator; // TODO use a more appropriate allocator
var server = net.StreamServer.init(.{});
defer server.deinit();
var room = Room{ .clients = std.AutoHashMap(*Client, void).init(allocator) };
try server.listen(net.Address.parseIp("127.0.0.1", 0) catch unreachable);
std.debug.warn("listening at {}\n", .{server.listen_address});
while (true) {
const client = try allocator.create(Client);
client.* = Client{
.conn = try server.accept(),
.handle_frame = async client.handle(&room),
};
try room.clients.putNoClobber(client, {});
}
}
const Client = struct {
conn: net.StreamServer.Connection,
handle_frame: @Frame(handle),
fn handle(self: *Client, room: *Room) !void {
try self.conn.file.writeAll("server: welcome to teh chat server\n");
while (true) {
var buf: [100]u8 = undefined;
const amt = try self.conn.file.read(&buf);
const msg = buf[0..amt];
room.broadcast(msg, self);
}
}
};
const Room = struct {
clients: std.AutoHashMap(*Client, void),
fn broadcast(room: *Room, msg: []const u8, sender: *Client) void {
var it = room.clients.iterator();
while (it.next()) |entry| {
const client = entry.key;
if (client == sender) continue;
client.conn.file.writeAll(msg) catch |e| std.debug.warn("unable to send: {}\n", .{e});
}
}
};
Tested with zig 0.5.0+f7f563ea5. The latest master branch build
from https://ziglang.org/download/ should work just fine.
zig build-exe basic-tcp-chat.zig
./basic-tcp-chat
This will print "listening at listening at 127.0.0.1:$PORT"
To play with it you have to open 2 terminal windows and in each one
(replacing $PORT with the one printed):
nc 127.0.0.1 $PORT
Now the terminals can talk to each other when you type your message and press enter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment