Skip to content

Instantly share code, notes, and snippets.

@marijnfs
Forked from andrewrk/basic-tcp-chat.zig
Last active December 9, 2022 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save marijnfs/78b0cc13d76a19dffbced766726189ec to your computer and use it in GitHub Desktop.
Save marijnfs/78b0cc13d76a19dffbced766726189ec 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 {
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = &general_purpose_allocator.allocator;
var server = net.StreamServer.init(.{});
defer server.deinit();
// TODO handle concurrent accesses to this hash map
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.stream.write("server: welcome to teh chat server\n");
while (true) {
var buf: [100]u8 = undefined;
const amt = try self.conn.stream.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.keyIterator();
while (it.next()) |key_ptr| {
const client = key_ptr.*;
if (client == sender) continue;
_ = client.conn.stream.write(msg) catch |e| std.debug.warn("unable to send: {}\n", .{e});
}
}
};
Tested with zig 0.6.0+4e63ca. 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.
@rofrol
Copy link

rofrol commented Jul 26, 2021

Builds but seems the terminals does not talk to each other. I don't see message on another terminal after pressing enter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment