我正在嘗試編寫通過Unix套接字進行雙向通信的Perl代碼。它需要做以下事情:Socket消息掛起,直到線程在Perl中完成
- 客戶端代碼發送過來
- 服務器代碼讀取請求
- 服務器執行任何操作應該發生立即
- 服務器套接字的請求創建一個新的線程來這樣做可能需要很長的時間
- 服務器發送響應在插座的附加動作
- 客戶端接收響應
- 新線程在響應發送後繼續工作
我已經獲得了大部分此功能,但有一個問題。步驟1 - 5正常工作,但在步驟6,客戶端無法讀取響應,直到線程退出後。 (儘管立即發送響應或多或少)任何想法我做錯了什麼?
我在Ubuntu Lucid上使用Perl 5.10.1。
下面是一個例子:
客戶端代碼:
#!/usr/bin/perl
use strict;
use Socket;
my $socket_name = 'catsock';
my $client_message = "Hello server, this is the client.";
my $SOCK;
socket($SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
connect($SOCK, sockaddr_un($socket_name)) or die "connect: $!";
$| = 1, select $_ for select $SOCK; # turn on autoflush
print $SOCK $client_message; # send the message
shutdown($SOCK,1); # finished writing
print "sent: $client_message\n";
my $server_message = do { local $/; <$SOCK> }; # get the response
print "recieved: $server_message\n\n";
Server代碼
#!/usr/bin/perl
use strict;
use Socket;
use threads;
use threads::shared;
sub threadfunc
{
print " waiting 5 seconds in new thread...\n";
sleep(5);
print " exiting thread...\n\n";
}
my $server_message = "Hello client, this is the server.";
my $socket_name = 'catsock';
my $SERVER;
my $CLIENT;
socket($SERVER, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
unlink($socket_name);
bind($SERVER, sockaddr_un($socket_name)) or die "bind: $!";
chmod(0660, $socket_name);
listen($SERVER, SOMAXCONN) or die "listen: $!";
print "server started on $socket_name\n\n";
while(1) {
accept($CLIENT, $SERVER);
my $client_message = do { local $/; <$CLIENT> }; # grab entire message
print "recieved: $client_message\n";
print "creating new thread...\n";
my $thr = threads->create(\&threadfunc);
$thr->detach();
print $CLIENT $server_message; # send the response
print "sent: $server_message\n\n";
close $CLIENT;
}
當我運行此,下面的事情發生:
- 客戶端發送「Hello服務器,這是客戶端。」
- 服務器收到客戶端的消息
- 服務器創建一個新線程
- 服務器發送「你好客戶端,這是服務器。」
- 客戶端應該現在收到消息,但它沒有。
- 在服務器上的新線程休眠5秒
- 線程退出
- 現在客戶端收到服務器的消息,即使它在5秒前發出。爲什麼?
設置'$ CLIENT'在接受後自動刷新? – 2010-09-10 02:43:43
是否有可能服務器線程在$ thread-> detach方法中被阻塞,並且因此$ CLIENT上的寫入沒有執行直到工作線程退出? – feroze 2010-09-10 04:05:28
@feroze - 額外的線程保持連接打開5秒(雖然我不確定如何 - 線程有一個'$ CLIENT'的私人副本,並且連接不會關閉,直到所有副本都沒有範圍,也許),但它不會延遲寫入'$ CLIENT'。 – mob 2010-09-10 04:28:35