2
0

main.zig 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. const std = @import("std");
  2. const net = std.net;
  3. const posix = std.posix;
  4. pub fn main() !void {
  5. const address = try std.net.Address.parseIp("127.0.0.1", 6000);
  6. const tpe: u32 = posix.SOCK.STREAM;
  7. const protocol = posix.IPPROTO.TCP;
  8. const listener = try posix.socket(address.any.family, tpe, protocol);
  9. defer posix.close(listener);
  10. try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
  11. try posix.bind(listener, &address.any, address.getOsSockLen());
  12. try posix.listen(listener, 128);
  13. while (true) {
  14. var client_address: net.Address = undefined;
  15. var client_address_len: posix.socklen_t = @sizeOf(net.Address);
  16. const socket = posix.accept(listener, &client_address.any, &client_address_len, 0) catch |err| {
  17. std.debug.print("error accept: {any}\n", .{err});
  18. continue;
  19. };
  20. defer posix.close(socket);
  21. std.debug.print("Connection received\n", .{});
  22. var buf: [128]u8 = undefined;
  23. const n = try read(socket, &buf);
  24. std.debug.print("Read {d} bytes: {s}\n", .{ n, buf[0..n] });
  25. try parseMessage(buf[0..n]);
  26. write(socket, "congratulations") catch |err| {
  27. // This can easily happen, say if the client disconnects.
  28. std.debug.print("error writing: {any}\n", .{err});
  29. };
  30. }
  31. }
  32. const Command = enum {
  33. read,
  34. write,
  35. delete,
  36. status,
  37. };
  38. fn parseKeyValue(buf: []const u8) ?[2][]const u8 {
  39. var kvIterator = std.mem.splitAny(u8, buf, "|");
  40. const key = kvIterator.first();
  41. const value = kvIterator.next() orelse {
  42. std.debug.print("No value found for key: {s}\n", .{key});
  43. return null;
  44. };
  45. std.debug.print("Parsed key: {s}, value: {s}\n", .{ key, value });
  46. return [2][]const u8{ key, value };
  47. }
  48. fn parseMessage(buf: []const u8) !void {
  49. var messageIterator = std.mem.splitAny(u8, buf, " ");
  50. const command = std.meta.stringToEnum(Command, messageIterator.first()) orelse {
  51. std.debug.print("Failed to parse command\n", .{});
  52. return;
  53. };
  54. switch (command) {
  55. .read => {
  56. std.debug.print("Read command received\n", .{});
  57. },
  58. .write => {
  59. std.debug.print("Write command received\n", .{});
  60. const kvPair = messageIterator.next() orelse {
  61. std.debug.print("No key-value pair provided for read command\n", .{});
  62. return;
  63. };
  64. const kv = parseKeyValue(kvPair) orelse {
  65. std.debug.print("Failed to parse key-value pair\n", .{});
  66. return;
  67. };
  68. std.debug.print("Key: {s}, Value: {s}\n", .{ kv[0], kv[1] });
  69. },
  70. .delete => std.debug.print("Delete command received\n", .{}),
  71. .status => std.debug.print("Status command received\n", .{}),
  72. }
  73. }
  74. fn read(socket: posix.socket_t, buf: []u8) !usize {
  75. var pos: usize = 0;
  76. while (pos < buf.len) {
  77. const n = try posix.read(socket, buf[pos..]);
  78. if (n == 0) {
  79. return pos; // connection closed
  80. }
  81. pos += n;
  82. }
  83. return pos;
  84. }
  85. fn write(socket: posix.socket_t, msg: []const u8) !void {
  86. var pos: usize = 0;
  87. while (pos < msg.len) {
  88. const written = try posix.write(socket, msg[pos..]);
  89. if (written == 0) {
  90. return error.Closed;
  91. }
  92. pos += written;
  93. }
  94. }