socktest2.zig 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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/socktest2.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_DGRAM, 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. std.debug.print("Zig UDP server is listening {s}\n", .{SOCKET_PATH});
  28. var buffer: [256]u8 = undefined;
  29. var sender_addr: c.struct_sockaddr_un = undefined;
  30. var addr_len: c.socklen_t = @sizeOf(c.struct_sockaddr_un);
  31. while(true){
  32. const n_bytes = c.recvfrom(
  33. sock,
  34. &buffer,
  35. buffer.len,
  36. 0,
  37. @ptrCast(&sender_addr),
  38. &addr_len
  39. );
  40. if(n_bytes <= 0){
  41. std.debug.print("receive error\n", .{});
  42. continue;
  43. }
  44. const msg = buffer[0..@intCast(n_bytes)];
  45. std.debug.print("receive msg: {s}\n", .{msg});
  46. // process msg
  47. var reply_buffer: [128]u8 = undefined;
  48. var fbs = std.io.fixedBufferStream(&reply_buffer);
  49. var writer = fbs.writer();
  50. if(std.mem.eql(u8, msg, "hello")){
  51. try writer.print("Hello World (by Zig) !", .{});
  52. }else if(std.mem.startsWith(u8, msg, "factorial ")){
  53. const num_str = msg["factorial ".len..];
  54. if(std.fmt.parseInt(usize, num_str, 10)) |num|{
  55. if(num > 34){ // max n for max factorial for u128
  56. try writer.print("error: input too large, max is 34", .{});
  57. }else{
  58. var fact: u128 = 1;
  59. var i = num;
  60. while(i > 1) : (i -= 1){ fact *= i; }
  61. try writer.print("factorial({d}) = {d}", .{ num, fact });
  62. }
  63. }else |_|{
  64. try writer.print("error: invalid number", .{});
  65. }
  66. }else{
  67. try writer.print("unknown command", .{});
  68. }
  69. const reply = fbs.getWritten();
  70. _ = c.sendto( // send responce
  71. sock,
  72. reply.ptr,
  73. reply.len,
  74. 0,
  75. @ptrCast(&sender_addr),
  76. addr_len
  77. );
  78. }
  79. }