From df26827a3f00d64f5af01271818c7c8bd7eaa387 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Fri, 5 Apr 2024 00:57:56 +0100 Subject: start of networking, and packet_reader --- server/main.ha | 143 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 34 deletions(-) (limited to 'server') diff --git a/server/main.ha b/server/main.ha index 43bdf34..f1eec0a 100644 --- a/server/main.ha +++ b/server/main.ha @@ -1,43 +1,118 @@ use fmt; -use os; +use net; +use net::tcp; +use net::ip; use io; -use fs; -use errors; -use drawing::{pos}; +use os; +use unix::poll; +use bufio; -// type chunk = struct { -// fd: io::file, -// d: []u32, -// }; +def PORT: u16 = 41460; -// def CHUNKSIZE: size = 512; -// def CHUNK_LENGTH: size = CHUNKSIZE*CHUNKSIZE*size(u32); - -// fn open_chunk_file(chunkpos: pos) (chunk | fs::error) = { -// const path = fmt::asprintf("c.{}.{}.dat", chunkpos.0, chunkpos.1); -// defer free(path); -// const fd = fs::create_file(os::cwd, path, -// fs::mode::USER_RW | fs::mode::GROUP_RW, -// fs::flag::RDWR)?; -// io::trunc(fd, CHUNK_LENGTH)?; -// const dp = io::mmap(null, CHUNK_LENGTH, -// io::prot::READ | io::prot::WRITE, -// io::mflag::SHARED, -// fd, 0)?; -// const d = (dp: *[*]u32)[..CHUNKSIZE*CHUNKSIZE]; -// return chunk { fd = fd, d = d }; -// }; +type conn = net::socket; + +type packet = []u8; +def PCKSZ: size = 4; + +type packet_reader = struct { + buf: [256]u8, + good: []u8, +}; + +fn packet_reader_new() packet_reader = { + let pr = packet_reader { + buf = [0...], + ... + }; + pr.good = pr.buf[0..0]; + return pr; + +}; + +// call when input is ready. could block otherwise +fn packet_reader_read(pr: *packet_reader, sock: net::socket) (void | io::error | io::EOF) = { + const remaining_amt = len(pr.good); + const read_pos = if (remaining_amt > 0) { + // still some unconsumed content in the buffer + // move unconsumed stuff to start of buffer + fmt::printfln("moving {} remaining bytes",remaining_amt)!; + pr.buf[0..remaining_amt] = pr.good; + yield remaining_amt; + } else 0z; + const nread = match(io::read(sock, pr.buf[read_pos..])?) { + case io::EOF => return io::EOF; + case let n: size => yield n; + }; + fmt::printfln("read {} bytes",nread)!; + const total_amt = read_pos + nread; + pr.good = pr.buf[0..total_amt]; + fmt::printfln("now {} bytes in buffer",total_amt)!; +}; + + +fn packet_reader_next(pr: *packet_reader) (packet | done) = { + // either parse a full packet out of the front of good, + // move good along that many bytes, + // and return the packet, + // or, ascertain there is no full packet, and return done + if (len(pr.good) < PCKSZ) return done; + const packet_bytes = pr.good[..PCKSZ]; + pr.good = pr.good[PCKSZ..]; + return packet_bytes; +}; export fn main() void = { - // match (open_chunk_file((-3,12))) { - // case let e: fs::error => - // fmt::fatal(fs::strerror(e)); - // case let ch: chunk => - // ch.d[0] = 0x12345678; - // ch.d[CHUNKSIZE*CHUNKSIZE - 1]=0xdeadbeef; - // }; + const listener = tcp::listen(ip::ANY_V4, PORT)!; + const conn = tcp::accept(listener)!; - const t = test2 { a=4, b=5 }; - thethe(&t); + const pr = packet_reader_new(); + for :mainloop (true) { + if (packet_reader_read(&pr, conn)! is io::EOF) + fmt::fatal("disconnected"); + let i = 0; + for (const packet => packet_reader_next(&pr)) { + fmt::printf("#{} got {}:",i,len(packet))!; + i+=1; + for (let byte .. packet) fmt::printf(" {:x}",byte)!; + fmt::println("")!; + }; + }; }; + + +// fn loop(listener: net::socket) void = { +// const buf: [256]u8 = [0...]; +// let pollfds: []poll::pollfd = alloc([ poll::pollfd { +// fd = listener, events = poll::event::POLLIN, revents = 0 +// }]); + +// for (true) { +// poll::poll(pollfds, poll::INDEF)!; +// if (0 != pollfds[0].revents & poll::event::POLLIN) { +// fmt::println("new conn")!; +// append(pollfds, poll::pollfd { +// fd = tcp::accept(pollfds[0].fd)!, +// events = poll::event::POLLIN, revents = 0 +// }); +// }; +// for (let i = 1z; i < len(pollfds); i += 1) { +// if (0 != pollfds[i].revents & poll::event::POLLIN) { +// match (io::read(pollfds[i].fd, buf)!) { +// case io::EOF => +// fmt::println("disconnect", i)!; +// delete(pollfds[i]); +// i -= 1; +// case let n: size => +// io::write(os::stdout_file, buf[..n])!; +// for (let j = 1z; j < len(pollfds); j += 1) { +// if (i != j) { +// io::writeall(pollfds[j].fd, buf[..n])!; +// }; +// }; +// }; +// }; + +// }; +// }; +// }; -- cgit v1.2.3