我在服务器和客户端之间有一个tcp连接,我正在寻找一种方法来轮询服务器端的输入端口。如果有任何可用数据,则应将其读取并放入列表中。我试着将它放在一个线程中,但这会阻塞,直到它可以读取内容,这不是我想要的。我希望线程在后台运行""。我想知道这是否有可能在球拍。
我有以下代码:
(define in '())
(define out '())
(define data '())
(define listener (tcp-listen 8085))
(define (discover)
(define (loop)
(if (tcp-accept-ready? listener)
(begin (let-values (((pi po) (tcp-accept listener)))
(set! in pi)
(set! out po)
(thread (read-thread pi)))
(loop))
'done))
(loop))
(define (read-thread port)
(let ((d (read port)))
(set! data (cons d data)))
(sleep 2)
(read-thread port))
答案 0 :(得分:3)
thread
过程需要thunk才能在新线程中运行。您的代码当前正在创建第二个线程之前进行读取(并且它应该给您一个关于thread
期望一个过程的错误)。你可能想要这个:
(thread (lambda () (read-thread pi)))
答案 1 :(得分:2)
你真的想读取字节,还是Racket表达式? (因为如果是后者,那么"之间会有一些紧张关系,等到你对我有完整的表达"和#34;但永远不会阻止"。)
也许字节可以,而且您只使用read
,因为您不了解read-bytes
?如果您使用的是read-bytes
,则可以将其替换为read-bytes-avail!*
,如果没有可供读取的字节,则会立即返回0。
如果您真的打算使用read
来阅读完整的Racket表达式,请注意read-bytes-avail!*
可以返回端口只有(x
,因为结束{ {1}}尚未到达。在这种情况下,解决这个问题的最佳方法可能取决于更多地了解您正在尝试完成的内容。但通常我建议使用)
和thread
- 即让Racket的轻量级线程处理"非阻塞"而不是自己动手。