100 lines
3.8 KiB
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 });
|
|
}
|