Re: [racket-users] Re: Detecting broken inbound TCP connections
Thanks Tony, I can confirm that eof-evt promptly delivers the expected information about the dropped TCP connection. Can an application promptly find out about dropped connections from any available HTTP library for racket? Jeff Tony Garnock-Jones unread, Jul 2, 2022, 9:23:51 AM (2 days ago) to Racket Users Ah, sorry, try `eof-evt` instead of `port-closed-evt`. When I swap the one for the other, your program gives the output you expected. Perhaps port closing is something for the Racket program to do, and is separate from the signalling from the remote peer. You'll get an `eof-object?` value from read routines when the connection closes. On 7/1/22 5:40 PM, George Neuner wrote: Hi Jeff, Note that most network problems result in an exception ... which your code is not catching and which you might have missed seeing in the output. You need to catch *exn:fail:network* and examine the *errno* field to figure out what happened. * errno* is a cons: *( integer . symbol )* of the error code and a symbol identifying the platform for which the error has meaning. The codes are (somewhat) platform dependent so you will need other references to decode them. For more, see: * https://docs.racket-lang.org/reference/exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn%29%29 * https://docs.racket-lang.org/reference/exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail~3anetwork~3aerrno%29%29 Hope this helps, George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/975b1936-107c-d525-ab06-c2ba4dcf4cd1%40gmail.com.
[racket-users] Re: Detecting broken inbound TCP connections
Ah, sorry, try `eof-evt` instead of `port-closed-evt`. When I swap the one for the other, your program gives the output you expected. Perhaps port closing is something for the Racket program to do, and is separate from the signalling from the remote peer. You'll get an `eof-object?` value from read routines when the connection closes. On Saturday, July 2, 2022 at 12:52:01 AM UTC+2 Jeff Henrikson wrote: > Hi Tony, > > Thanks for offering your interpretation of the racket reference manual. > Below is my attempt to test whether or not the input port does indeed > become closed when the TCP connection is broken. > > The broken TCP connection is provided by combining curl with GNU > coreutils timeout. > > I try testing the input port for closedness two different ways. The > default code tests with port-closed-evt. The commented out code tests by > calling port-closed? in a loop. Neither method succeeds in detecting > the broken TCP connection. > > Thanks for any help. > > Regards, > > > Jeff Henrikson > > > #lang racket > > ;; Tony Garnock-Jones, > https://groups.google.com/g/racket-users/c/H43jr8QuM-4 > ;; "... if the connection breaks, the ports will be closed as usual. . > . ." > > (define (handle-by-event in out k) > ; Discard the HTTP request header (up to blank line): > (regexp-match #rx"(\r\n|^)\r\n" in) > (displayln "about to sleep") > (flush-output (current-output-port)) > (let ((evt (sync/timeout 10 (port-closed-evt in > (if evt > (begin > (displayln "got close evt\n") > (k)) > (begin > (displayln "done sleeping") > (flush-output (current-output-port)) > (display "HTTP/1.0 200 Okay\r\n" out) > (display "Server: k\r\nContent-Type: text/html\r\n\r\n" out) > (display "Hello, world!" out) > (k) > > ;; same as handle-by-event but using port-closed? instead of > port-closed-evt > (define (handle-by-polling in out k) > (define (iter i) > (when (> i 0) > (printf "closed=~a\n" (port-closed? in)) > (sleep 1) > (iter (- i 1 > ; Discard the request header (up to blank line): > (regexp-match #rx"(\r\n|^)\r\n" in) > (displayln "about to sleep") > (flush-output (current-output-port)) > (iter 10) > (displayln "done sleeping") > (flush-output (current-output-port)) > (display "HTTP/1.0 200 Okay\r\n" out) > (display "Server: k\r\nContent-Type: text/html\r\n\r\n" out) > (display "Hello, world!" out) > (k)) > > > (define (accept-and-handle listener) > (define-values (in out) (tcp-accept listener)) > ;; alternatively: (handle-by-polling in out (lambda () > (handle-by-event in out (lambda () > (displayln "handle finished") > )) > (close-input-port in) > (close-output-port out)) > > (define (serve port-no) > (define listener (tcp-listen port-no 5 #t)) > (define (loop) > (accept-and-handle listener) > (loop)) > (loop)) > > (serve 8000) > > #| > Test with curl and GNU coreutils timeout: > timeout --foreground 3s curl http://127.0.0.1:8000 > actual output (handle-by-event version): > about to sleep > done sleeping > handle finished > expected output (handle-by-event version): > about to sleep > got close evt > handle finished > > Tested on: > Racket v8.0 cs > on Ubuntu 20.04.4 LTS > |# > > > > Hi Jeff, > > > > You can use `tcp-listen` and `tcp-accept` [0] to accept connections. > > Once accepted, the connection appears as a matched pair of ports, one > > for input and one for output, and if the connection breaks, the ports > > will be closed as usual. In some circumstances, you will get an > > exception such as "connection reset" (see `exn:fail:network`). If you > > need to reliably distinguish closed-by-peer, all-ok from > > closed-by-weird-network-weather, your application protocol has to > > handle that, there's nothing TCP can do for you there. HTTP does this > > via content-length and/or chunking, for example. > > > > Cheers, > > Tony > > > > [0]: https://docs.racket-lang.org/reference/tcp.html > > > > On 6/30/22 11:34 AM, Jeff Henrikson wrote: > >> Racket users, > >> > >> How do I accept an inbound TCP connection so that once I am > >> processing it, if the connection is broken by the client or network, > >> my program promptly finds out? > >> > >> Regards, > >> > >> > >> Jeff Henrikson > >> > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/9dae05ac-1a29-4384-976c-7c4e57dff197n%40googlegroups.com.
Re: [racket-users] Re: Detecting broken inbound TCP connections
Hi Jeff, Note that most network problems result in an exception ... which your code is not catching and which you might have missed seeing in the output. You need to catch *exn:fail:network* and examine the *errno* field to figure out what happened. * errno* is a cons: *( integer . symbol )* of the error code and a symbol identifying the platform for which the error has meaning. The codes are (somewhat) platform dependent so you will need other references to decode them. For more, see: * https://docs.racket-lang.org/reference/exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn%29%29 * https://docs.racket-lang.org/reference/exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail~3anetwork~3aerrno%29%29 Hope this helps, George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/31a25463-eb1e-2f05-920a-7cfa49e33f99%40comcast.net.
[racket-users] Re: Detecting broken inbound TCP connections
Hi Tony, Thanks for offering your interpretation of the racket reference manual. Below is my attempt to test whether or not the input port does indeed become closed when the TCP connection is broken. The broken TCP connection is provided by combining curl with GNU coreutils timeout. I try testing the input port for closedness two different ways. The default code tests with port-closed-evt. The commented out code tests by calling port-closed? in a loop. Neither method succeeds in detecting the broken TCP connection. Thanks for any help. Regards, Jeff Henrikson #lang racket ;; Tony Garnock-Jones, https://groups.google.com/g/racket-users/c/H43jr8QuM-4 ;; "... if the connection breaks, the ports will be closed as usual. . . ." (define (handle-by-event in out k) ; Discard the HTTP request header (up to blank line): (regexp-match #rx"(\r\n|^)\r\n" in) (displayln "about to sleep") (flush-output (current-output-port)) (let ((evt (sync/timeout 10 (port-closed-evt in (if evt (begin (displayln "got close evt\n") (k)) (begin (displayln "done sleeping") (flush-output (current-output-port)) (display "HTTP/1.0 200 Okay\r\n" out) (display "Server: k\r\nContent-Type: text/html\r\n\r\n" out) (display "Hello, world!" out) (k) ;; same as handle-by-event but using port-closed? instead of port-closed-evt (define (handle-by-polling in out k) (define (iter i) (when (> i 0) (printf "closed=~a\n" (port-closed? in)) (sleep 1) (iter (- i 1 ; Discard the request header (up to blank line): (regexp-match #rx"(\r\n|^)\r\n" in) (displayln "about to sleep") (flush-output (current-output-port)) (iter 10) (displayln "done sleeping") (flush-output (current-output-port)) (display "HTTP/1.0 200 Okay\r\n" out) (display "Server: k\r\nContent-Type: text/html\r\n\r\n" out) (display "Hello, world!" out) (k)) (define (accept-and-handle listener) (define-values (in out) (tcp-accept listener)) ;; alternatively: (handle-by-polling in out (lambda () (handle-by-event in out (lambda () (displayln "handle finished") )) (close-input-port in) (close-output-port out)) (define (serve port-no) (define listener (tcp-listen port-no 5 #t)) (define (loop) (accept-and-handle listener) (loop)) (loop)) (serve 8000) #| Test with curl and GNU coreutils timeout: timeout --foreground 3s curl http://127.0.0.1:8000 actual output (handle-by-event version): about to sleep done sleeping handle finished expected output (handle-by-event version): about to sleep got close evt handle finished Tested on: Racket v8.0 cs on Ubuntu 20.04.4 LTS |# Hi Jeff, You can use `tcp-listen` and `tcp-accept` [0] to accept connections. Once accepted, the connection appears as a matched pair of ports, one for input and one for output, and if the connection breaks, the ports will be closed as usual. In some circumstances, you will get an exception such as "connection reset" (see `exn:fail:network`). If you need to reliably distinguish closed-by-peer, all-ok from closed-by-weird-network-weather, your application protocol has to handle that, there's nothing TCP can do for you there. HTTP does this via content-length and/or chunking, for example. Cheers, Tony [0]: https://docs.racket-lang.org/reference/tcp.html On 6/30/22 11:34 AM, Jeff Henrikson wrote: Racket users, How do I accept an inbound TCP connection so that once I am processing it, if the connection is broken by the client or network, my program promptly finds out? Regards, Jeff Henrikson -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/e3445bfa-8d75-bbf5-1900-226a67e71599%40gmail.com.
[racket-users] Re: Detecting broken inbound TCP connections
Hi Jeff, On Thursday, June 30, 2022 at 8:34:44 PM UTC+2 Jeff Henrikson wrote: > How do I accept an inbound TCP connection so that once I am processing > it, if the connection is broken by the client or network, my program > promptly finds out? > You can use `tcp-listen` and `tcp-accept` [0] to accept connections. Once accepted, the connection appears as a matched pair of ports, one for input and one for output, and if the connection breaks, the ports will be closed as usual. In some circumstances, you will get an exception such as "connection reset" (see `exn:fail:network`). If you need to reliably distinguish closed-by-peer, all-ok from closed-by-weird-network-weather, your application protocol has to handle that, there's nothing TCP can do for you there. HTTP does this via content-length and/or chunking, for example. Cheers, Tony [0]: https://docs.racket-lang.org/reference/tcp.html -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/d0a1ace1-e14f-4062-8d83-f160165ef9a5n%40googlegroups.com.