socktest.zig 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. const std = @import("std");
  2. const c = @cImport({
  3. @cInclude("sys/socket.h");
  4. @cInclude("sys/un.h");
  5. @cInclude("unistd.h");
  6. });
  7. const SOCKET_PATH = "/tmp/socktest.sock";
  8. pub fn main() !void{
  9. std.fs.deleteFileAbsolute(SOCKET_PATH) catch {}; // delete old if exists
  10. const sock = c.socket(c.AF_UNIX, c.SOCK_STREAM, 0); // create new TCP sock, Unix domain (TCP-like)
  11. if(sock == -1){
  12. std.debug.print("failed to create socket\n", .{});
  13. return error.SocketCreateFailed;
  14. }
  15. defer _ = c.close(sock);
  16. var addr: c.struct_sockaddr_un = undefined;
  17. addr.sun_family = c.AF_UNIX;
  18. if(SOCKET_PATH.len >= addr.sun_path.len){
  19. return error.SocketPathTooLong;
  20. }
  21. @memcpy(addr.sun_path[0..SOCKET_PATH.len], SOCKET_PATH);
  22. addr.sun_path[SOCKET_PATH.len] = 0;
  23. if(c.bind(sock, @ptrCast(&addr), @sizeOf(c.struct_sockaddr_un)) == -1){
  24. std.debug.print("failed to bind socket\n", .{});
  25. return error.SocketBindFailed;
  26. }
  27. if(c.listen(sock, 1) == -1){
  28. std.debug.print("failed to listen socket\n", .{});
  29. return error.SocketListenFailed;
  30. }
  31. std.debug.print("Zig server is listening {s}\n", .{SOCKET_PATH});
  32. while(true){
  33. const client_fd = c.accept(sock, null, null);
  34. if(client_fd == -1){
  35. std.debug.print("accept error\n", .{});
  36. continue;
  37. }
  38. std.debug.print("client connected\n", .{});
  39. const file = std.fs.File{ .handle = @intCast(client_fd) };
  40. const in_stream = file.reader();
  41. const out_stream = file.writer();
  42. var buffer: [256]u8 = undefined;
  43. const n_bytes = in_stream.read(&buffer) catch |err|{ // read msg
  44. std.debug.print("read msg err: {any}\n", .{err});
  45. _ = c.close(client_fd);
  46. continue;
  47. };
  48. const msg = buffer[0..n_bytes];
  49. std.debug.print("receive msg: {s}\n", .{msg});
  50. // process msg
  51. var reply_buffer: [128]u8 = undefined;
  52. var fbs = std.io.fixedBufferStream(&reply_buffer);
  53. var writer = fbs.writer();
  54. if(std.mem.eql(u8, msg, "hello")){
  55. try writer.print("Hello World (by Zig) !", .{});
  56. }else if(std.mem.startsWith(u8, msg, "factorial ")){
  57. const num_str = msg["factorial ".len..];
  58. if(std.fmt.parseInt(usize, num_str, 10)) |num|{
  59. if(num > 34){ // max n for max factorial for u128
  60. try writer.print("error: input too large, max is 34", .{});
  61. }else{
  62. var fact: u128 = 1;
  63. var i = num;
  64. while(i > 1) : (i -= 1){ fact *= i; }
  65. try writer.print("factorial({d}) = {d}", .{ num, fact });
  66. }
  67. }else |_|{
  68. try writer.print("error: invalid number", .{});
  69. }
  70. }else{
  71. try writer.print("unknown command", .{});
  72. }
  73. _ = try out_stream.write(fbs.getWritten()); // send responce
  74. _ = c.close(client_fd);
  75. }
  76. }