Hi, In a small Racket client/server over tcp, the client sends expressions that the server evaluates and returns the result to the client, in a loop. The tcp ports are flushed after each send, but it is still hanging, unless I wrap the sent values in lists, which is a bit surprising. So it looks like the buffer won't flush if it's not a list. Is that a bug (maybe related to http://bugs.racket-lang.org/query/?cmd=view&pr=12640 , but maybe not) or is it me? I can live with it though.
Client: #lang racket/base (require racket/tcp) (printf "Trying to connect to server... ") (define-values (in out) (tcp-connect "localhost" 54321)) (printf "Ok.\n") (dynamic-wind void (λ() (printf "rwind-client> ")(flush-output) (define exit? #f) (for ([e (in-port read)] #:break (or exit? (equal? e '(exit))) ) (printf "Sending: ~a\n" e) ; Wrap the output in a list, otherwise it may not be sent/flushed (bug?) (write (list e) out) (flush-output out) ; receiving from server, unwrap (define res (car (read in))) (if (eof-object? res) (set! exit? #t) (begin (printf "-> ~a\n" res) (printf "rwind-client> ")(flush-output))) )) (λ() (printf "Closing connection.\n") (close-input-port in) (close-output-port out))) Server: #lang racket/base (require racket/tcp) (define-namespace-anchor a) (define ns (namespace-anchor->namespace a)) (let () ; does this protect the listener from being visible to the namespace? (define listener (tcp-listen 54321)) (dynamic-wind void (λ() ;; Blocking (let accept-loop () (printf "Waiting for client... ")(flush-output) (define-values (in out) (tcp-accept listener)) (printf "Client is connected.\n") (dynamic-wind void (λ() (for ([e (in-port read in)] #:break (equal? e '(exit)) ) (printf "Received ~a\n" e) ;(flush-output) (define res ; if it fails, simply return the message (with-handlers ([exn:fail? (λ(e)(exn-message e))]) ; unwrap (eval (car e) ns))) (printf "Sending value: ~a ... " res) (flush-output) ; I need to wrap the output in a list, otherwise it may not be sent/flushed! (bug?) (write (list res) out) (flush-output out) (printf "Ok.\n") )) (λ() (printf "Closing connection.\n") (close-input-port in) (close-output-port out) ;(accept-loop) ; uncomment this to not close the listener when the client disconnects )))) ; out (λ()(tcp-close listener)))) Also, unrelated to the problem above, I want to close everything correctly when a problem occurs, but it seems that dynamic wind does not do that in case of a break (e.g., if the exn handler is removed, an invalid operation will raise an exception, but the ports will not be closed). I may be misunderstanding what dynamic-wind does. What would be the "right" way to do things here? Thanks, Laurent
____________________ Racket Users list: http://lists.racket-lang.org/users