2
0

socket.zig 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. const std = @import("std");
  2. const net = std.net;
  3. const posix = std.posix;
  4. pub fn setReadTimeout(conn: posix.socket_t, seconds: u32) !void {
  5. const timeout = posix.timeval{
  6. .sec = @intCast(seconds),
  7. .usec = 0,
  8. };
  9. try posix.setsockopt(conn, posix.SOL.SOCKET, posix.SO.RCVTIMEO, &std.mem.toBytes(timeout));
  10. }
  11. pub fn setWriteTimeout(conn: posix.socket_t, seconds: u32) !void {
  12. const timeout = posix.timeval{
  13. .sec = @intCast(seconds),
  14. .usec = 0,
  15. };
  16. try posix.setsockopt(conn, posix.SOL.SOCKET, posix.SO.SNDTIMEO, &std.mem.toBytes(timeout));
  17. }
  18. pub fn init(host: []const u8, port: u16) !posix.socket_t {
  19. const address = try std.net.Address.parseIp(host, port);
  20. const tpe: u32 = posix.SOCK.STREAM;
  21. const protocol = posix.IPPROTO.TCP;
  22. const listener = try posix.socket(address.any.family, tpe, protocol);
  23. try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
  24. try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.RCVBUF, &std.mem.toBytes(@as(c_int, 1048576))); // 1MB receive buffer
  25. try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.SNDBUF, &std.mem.toBytes(@as(c_int, 1048576))); // 1MB send buffer
  26. try posix.bind(listener, &address.any, address.getOsSockLen());
  27. try posix.listen(listener, 1024); // Increased backlog
  28. return listener;
  29. }
  30. pub fn initUnix(path: []const u8) !posix.socket_t {
  31. posix.unlink(path) catch {};
  32. const address = try net.Address.initUnix(path);
  33. const listener = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM, 0);
  34. try posix.bind(listener, &address.any, address.getOsSockLen());
  35. try posix.listen(listener, 1024);
  36. return listener;
  37. }
  38. pub fn readUntilCR(conn: posix.socket_t, buf: []u8) !usize {
  39. var total: usize = 0;
  40. while (total < buf.len) {
  41. const n = try posix.read(conn, buf[total..]);
  42. if (n == 0) {
  43. return if (total > 0) total else error.ConnectionClosed;
  44. }
  45. if (std.mem.indexOfScalar(u8, buf[total .. total + n], '\r')) |offset| {
  46. return total + offset;
  47. }
  48. total += n;
  49. }
  50. return total;
  51. }
  52. pub fn read(conn: posix.socket_t, buf: []u8) !usize {
  53. var pos: usize = 0;
  54. while (pos < buf.len) {
  55. const n = try posix.read(conn, buf[pos..]);
  56. if (n == 0) {
  57. return pos;
  58. }
  59. pos += n;
  60. }
  61. return pos;
  62. }
  63. pub fn write(conn: posix.socket_t, msg: []const u8) !void {
  64. var offset: usize = 0;
  65. while (offset < msg.len) {
  66. const written = try posix.write(conn, msg[offset..]);
  67. if (written == 0) return error.ConnectionClosed;
  68. offset += written;
  69. }
  70. }
  71. pub fn writev(conn: posix.socket_t, iovecs: []const posix.iovec_const) !void {
  72. for (iovecs) |iov| {
  73. const bytes: [*]const u8 = @ptrCast(iov.base);
  74. try write(conn, bytes[0..iov.len]);
  75. }
  76. }