Skip to content

Commit cea4b2e

Browse files
committed
Closes #1; detect server closing connection properly
1 parent a3c51c6 commit cea4b2e

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

src/client.zig

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,47 @@ pub const Client = struct {
1919
state: State,
2020
game: ?Game = null,
2121
nameIter: NameIterator = undefined,
22+
gamesLeft: ?u32 = undefined,
23+
shouldRun: bool = true,
2224

2325
/// sets up TCP connection
2426
/// after init .game is still null, .game will be initialized in .parse() if client recieves c message from server
25-
pub fn init(hostname: []const u8, port: u16) !Client {
27+
pub fn init(hostname: []const u8, port: u16, gamesToPlay: ?u32) !Client {
2628
const peer = try std.net.Address.parseIp4(hostname, port);
2729
const strm = try std.net.tcpConnectToAddress(peer);
2830
try std.io.getStdOut().writer().print("connected to: {s}:{d}\n", .{ hostname, port });
29-
return Client{ .stream = strm, .state = State.Connected };
31+
return Client{
32+
.stream = strm,
33+
.state = State.Connected,
34+
.gamesLeft = gamesToPlay,
35+
};
3036
}
3137

3238
/// reads from socket stream until delimiter is found
3339
/// if message delimiter \n is found => calls self.parse()
3440
/// should block until finds delimiter, but instead throws error if delimiter not found in stream - TO FIX
35-
pub fn read(self: *Client, allocator: Allocator) !bool {
41+
pub fn read(self: *Client, allocator: Allocator) !void {
3642
var buff = std.ArrayList(u8).init(allocator);
3743
defer buff.deinit();
38-
self.stream.reader().streamUntilDelimiter(buff.writer(), '\n', null) catch {
39-
try std.io.getStdOut().writer().print("server closed the connection\n", .{});
40-
return false;
41-
};
4244

43-
if (buff.items.len == 0) {
44-
try std.io.getStdOut().writer().print("server closed the connection\n", .{});
45-
return false;
45+
var run = true;
46+
var prevLen = buff.items.len;
47+
while (run) {
48+
run = false;
49+
self.stream.reader().streamUntilDelimiter(buff.writer(), '\n', null) catch |err| {
50+
if (err == error.EndOfStream) {
51+
if (buff.items.len == prevLen) { // no new bytes found - meaning received 0 bytes in last read - meaning server closed connection
52+
try std.io.getStdOut().writer().print("server closed the connection\n", .{});
53+
self.shouldRun = false;
54+
return;
55+
} else run = true; // end of stream reached, got some bytes, but no delimiter (hopefully remaining bytes will get there soon)
56+
} else return err;
57+
};
58+
prevLen = buff.items.len;
4659
}
4760
// print("MSG: {s}\n", .{buff.items});
4861

4962
try self.parse(buff.items, allocator);
50-
return true;
5163
}
5264

5365
/// sends msg to server in a blocking manner
@@ -271,15 +283,30 @@ pub const Client = struct {
271283
}
272284
}
273285

286+
/// decrement value of games left to play
287+
/// if it reaches 0 then set stop operation flag
288+
fn decrementGameCounter(self: *Client) void {
289+
if (self.gamesLeft) |*gl| {
290+
std.debug.assert(gl.* > 0);
291+
gl.* -= 1;
292+
if (gl.* == 0) self.shouldRun = false;
293+
}
294+
}
295+
274296
/// client loop
275297
/// runs forever or until an error is thrown somewere
276298
pub fn loop(self: *Client, allocator: Allocator) void {
277-
while (self.read(allocator) catch false) {}
299+
while (self.shouldRun) {
300+
self.read(allocator) catch |err| {
301+
self.shouldRun = false;
302+
print("execution stopped due to error: {s}\n", .{@errorName(err)});
303+
};
304+
}
278305
}
279306

280307
pub fn deinit(self: *Client) void {
281308
self.stream.close();
282-
self.game.?.deinit();
309+
if (self.game) |*cgame| cgame.deinit();
283310
}
284311
};
285312

src/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn main() !void {
3232
};
3333
const port = try std.fmt.parseInt(u16, port_value, 10);
3434

35-
var cli = try Client.init(host_value, port);
35+
var cli = try Client.init(host_value, port, null);
3636
defer cli.deinit();
3737
cli.loop(allocator);
3838
}

0 commit comments

Comments
 (0)