2014-04-14 62 views
2

我在服務器和客戶機之間有一個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)) 

回答

3

thread過程需要一個thunk在新的線程中運行。你的代碼目前正在做第二個線程創建之前的閱讀(它應該給你一個關於thread期待一個過程的錯誤)。你可能想要這個:

(thread (lambda() (read-thread pi))) 
2

你真的要讀取的字節,或者,球拍表情? (因爲如果是後者,在「等到你對我有完整的表達方式」和「但是從不阻止」之間存在一些緊張關係)。

也許字節會好的,並且你僅僅使用read,因爲你沒有知道read-bytes?如果您使用的是read-bytes,則可以用read-bytes-avail!*替換該值,如果沒有字節可供讀取,則立即返回0。

而如果你真的想用的read讀一個完整的球拍表達,要注意read-bytes-avail!*例如可以只用(x可返回在港口,因爲收盤)還沒有到達。在這種情況下,解決這個問題的最好方法可能取決於更多地瞭解你想要完成的任務。但通常我會建議使用threadread - 即讓Racket的輕量級線程處理「非阻塞」而不是自己做。

+0

我不知道'read-bytes'和'read-bytes-avail!*',也許我可以使用它。但我並不是很瞭解它,我如何將它與輸入端口一起使用?你能給出一些代碼來證明這一點嗎? – JNevens

+0

其實看到瑞恩的答案。 (當我回答時,我沒有注意到你已經使用'thread',但沒有正確使用它。) –