2013-01-13 37 views
2

客戶端:Perl的TCP,打印,選擇和sysread執行 - 緩衝行爲

$socket->autoflush(1); 
print $socket "abel\n"; 
print $socket "baker\n"; 
print $socket "charlie\n"; 

我的問題:

當服務器的select()(或can_read)完成後,做什麼保證我有內容系統receive緩衝區?它是否可能包含一個「a」?或者「abel \ nbak」?或者系統緩衝區保證準確地包含客戶端中相應的'打印'語句發送的字符串中的一個,兩個或全部三個?

這顯然對我如何管理應用程序級緩衝區有影響。

回答

2

沒有這樣的保證TCP(和SOCK_STREAM一般)。你列出的任何東西都是可能的。

+0

我很懷疑。偶然的機會是,在更高級別上實現select()的Perl模塊,表明可以在不阻塞的情況下檢索完整的行結束符字符串?還是我必須自己管理? – Chap

+1

我不知道Perl,但例如在TCL中,我們使套接字處於非阻塞模式,並使用普通的'gets'(即高級讀線功能)。如果該行不完整,它只是返回「無」(帶有標誌),但部分行保持緩衝。所以我們只需在「獲取」失敗時再次「選擇」。 Perl必須有相同的東西。 –

+0

我幾乎是積極的,我從來不知道它是什麼。謝謝 - 你已經回答了我的問題。 – Chap

0

沒有保證。 「a」和「abel \ nbak」都是可能的。

sysread如果有數據可用,則不會阻塞;它會返回可用的內容。因此,您可以使用

for my $fh (@ready) { 
    my $close = 0; 
    my $client = $clients{$fh}; 

    our $buf; local *buf = $client->{buf}; 
    my $rv = sysread($buf, 0, 64*1024, length($buf)); 
    if ($rv) { 
     while ($buf =~ s/^(.*)\n//) { 
     my $msg = $1; 
     $close = 1 if process_msg($msg); 
     } 
    } else { 
     $close = 1; 
     # Handle error and eof here. 
    } 

    if ($close) { 
     $readers->delete($fh); 
     delete $clients->{$fh}; 
    } 
}