Hello,
I am having some trouble fixing a "bug" in
QCmd 0.2a, and wondered if you could help.
QCmd works fine on most queries where a simple sendto/recvfrom is enough, but some very useful ones, such as
rcon status, dir & quit, work in quite a different way:
Intead of just sending one backslash-separated datagram, the server sends each line in a different packet, prefixed by "????????????print". So I need as many recvfrom calls as there are lines.
Trouble is, I don't know in advance how many lines the server is sending me, so when I try to read it all, I systematically end up with a socket timeout on the last recvfrom. I could catch it and deal with it, of course,but
waiting for it takes time. I want to avoid the timeout altogether.
I first thought the server's last packet would be something special I could look out for, but there seems to be no consistency whatsoever between, say,
status and
quit, so I would have to come up with adhoc solutions for each query. No dice.
Then I thought I would test for an end of file condition, and tried the following:
OCaml code (testing for eof)
Code:
(* display all lines of in_channel ch on stdout *)
let rec disp_inchan ch = try pl (input_line ch) ; disp_inchan ch with End_of_file -> ()
(* DEBUG: returns dummy string, but prints everything received. Needs eof condition *)
let recv_dgram sock = let ic = in_channel_of_descr sock in disp_inchan ic; "<<dummy output>>"
(I suppose that's roughly equivalent to something like a
while (!eof(sock)) read...; printf...; in C)
Output (the exception amounts to a socket timeout)Code:
q3sock testing >>
????????????print
map: the_academy_v3
????????????print
num score ping name lastmsg address qport rate
????????????print
--- ----- ---- --------------- ------- --------------------- ----- -----
????????????print
0 3 0 ^3{<??? ^1Bot Idi 50 bot 0 16384
????????????print
1 2 0 ^3{<??? ^1Bot B???t 50 bot 0 16384
????????????print
8 0 999 ^7:^0Cpt^7.^0???p 28250 82.128.241.72:29070 53242 25000
????????????print
????????????print
Fatal error: exception Sys_blocked_io /// NOTE: comes only after the socket timeout
Clearly it doesn't work as expected: there is no end of file condition.
So, do you have any idea how I could know nothing else has been sent, without needing to try a recvfrom and wait for a socket timeout ?
Thanks,
Gamall Wednesday Ida.