Backlog/lib/enet/src/test_server.zig

100 lines
3.8 KiB
Zig

const std = @import("std");
const enet = @import("enet");
const enetc = enet.c;
const SERVER_PORT = 7777;
const MAX_CLIENTS = 32;
const CHANNEL_COUNT = 2;
pub fn main() !void {
std.debug.print("Starting ENet test server on port {}\n", .{SERVER_PORT});
// Initialize ENet
try enet.initialize();
defer enet.deinitialize();
// Create server address
var address = enetc.ENetAddress{
.host = enetc.ENET_HOST_ANY,
.port = SERVER_PORT,
};
// Create host
const host = enetc.enet_host_create(&address, MAX_CLIENTS, CHANNEL_COUNT, 0, 0) orelse {
std.debug.print("Failed to create ENet server host\n", .{});
return error.HostCreationFailed;
};
defer enetc.enet_host_destroy(host);
std.debug.print("ENet server listening on port {} (waiting for clients...)\n", .{SERVER_PORT});
var running = true;
var client_count: u32 = 0;
var message_count: u32 = 0;
while (running) {
var event: enetc.ENetEvent = undefined;
// Service the host with a 1000ms timeout
const result = enetc.enet_host_service(host, &event, 1000);
if (result > 0) {
switch (event.type) {
enetc.ENET_EVENT_TYPE_CONNECT => {
client_count += 1;
std.debug.print("Client connected from {}:{} (total clients: {})\n", .{ event.peer.*.address.host, event.peer.*.address.port, client_count });
// Send welcome message
const welcome_msg = "Welcome to ENet test server!";
if (enetc.enet_packet_create(welcome_msg.ptr, welcome_msg.len, enetc.ENET_PACKET_FLAG_RELIABLE)) |packet| {
_ = enetc.enet_peer_send(event.peer, 0, packet);
}
},
enetc.ENET_EVENT_TYPE_RECEIVE => {
message_count += 1;
const data = @as([*]u8, @ptrCast(event.packet.*.data))[0..event.packet.*.dataLength];
std.debug.print("Received message #{}: '{s}'\n", .{ message_count, data });
// Echo the message back to the client
const echo_msg = std.fmt.allocPrint(std.heap.page_allocator, "Echo: {s}", .{data}) catch "Echo: (allocation failed)";
defer if (!std.mem.eql(u8, echo_msg, "Echo: (allocation failed)")) std.heap.page_allocator.free(echo_msg);
if (enetc.enet_packet_create(echo_msg.ptr, echo_msg.len, enetc.ENET_PACKET_FLAG_RELIABLE)) |packet| {
_ = enetc.enet_peer_send(event.peer, 0, packet);
}
// Destroy the received packet
enetc.enet_packet_destroy(event.packet);
// If this is a "quit" message, stop the server
if (std.mem.eql(u8, data, "quit")) {
std.debug.print("Received quit command, shutting down server...\n", .{});
running = false;
}
},
enetc.ENET_EVENT_TYPE_DISCONNECT => {
client_count -= 1;
std.debug.print("Client disconnected (total clients: {})\n", .{client_count});
event.peer.*.data = null;
},
else => {},
}
} else if (result < 0) {
std.debug.print("Error servicing host\n", .{});
break;
}
// Stop server if no clients and we've processed some messages
if (client_count == 0 and message_count > 0) {
std.debug.print("No clients connected, shutting down...\n", .{});
break;
}
}
std.debug.print("Server shutting down. Processed {} messages from {} client connections.\n", .{ message_count, client_count });
}