作者tonini (LPI Course Ongoing)
看板Perl
标题Re: [问题] 请问一下Server-Client的问题
时间Mon Apr 27 17:13:14 2009
前文吃光光
在经过友人的鼎力相助之後~终於产出了这个程式
我的贡献度应该有~~~0.1%
都是朋友写的XDDD
也PO上来让大家参考一下
Server:
===========================
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
use threads;
use threads::shared;
my $port = 8000;
my $read_wait = 2000000;
my $write_wait = 5000000;
#========================================================================================
my %clients;
my $writing :shared;
my @data_arr :shared = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
# 当行程结束时,kernel会向他的父行程发送一个 CHLD 信号
# 因为我们的行程不会有NOHANG的状况,所以设成IGNORE才不会生出zombie
$SIG{CHLD} = 'IGNORE';
my $server = IO::Socket::INET->new(
LocalPort => $port,
Listen => SOMAXCONN, #最大连接数
Proto => 'tcp',
ReuseAddr => 1
) or die "Couldn't create a tcp server on port $port : $@\n";;
print "Server ready. Waiting for connections on port : $port ... \n";
while (my $client = $server->accept) {
# spawn a thread to handle the connection
# 因为没有要拿回传值,所以直接detach就好了
threads->create("request_process", $client)->detach;
}
sub request_process {
# accept data from the socket and put it on the queue
my $socket = shift;
my ($mode, $count, $data);
while (my $line = <$socket>) {
chomp($line);
last if $line eq 'finish';
($mode, $count, $data) = split /:/, $line;
print "client $count in, mode : $mode ", ($mode eq 'write' ? ", data : $data" : ''), "\n";
# the writer
if ($mode eq 'write') {
my @data_recv = split /,/, $data;
lock $writing;
$writing++; # 这个动作其实没有用到,只是怕他太无聊
lock @data_arr; # 其实不锁这个也可以
print "array is changing and locked by client $count.\n";
@data_arr[0, 1, 2, 3, 4] = @data_recv[0, 1, 2, 3, 4];
internal_loop($mode);
@data_arr[5, 6, 7, 8, 9] = @data_recv[5, 6, 7, 8, 9];
$writing--; # 这个动作其实没有用到,只是怕他太无聊
# the reader
} else {
lock $writing;
internal_loop($mode);
print $socket join ',', @data_arr, "\n";
print "client $count get the array\n";
}
}
print $socket "finish\n";
close $socket;
print "client $count out\n";
}
sub internal_loop {
my $time_wait = shift;
$time_wait = ($time_wait eq 'read' ? $read_wait : $write_wait);
for (1 .. $time_wait) {
#do nothing
}
}
Client:
________________________________________
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
use threads;
my $remote_host = '127.0.0.1';
my $remote_port = 8000;
$SIG{CHLD} = 'IGNORE';
for my $count (1 .. 49) {
my $server = IO::Socket::INET->new(
PeerAddr => $remote_host,
PeerPort => $remote_port,
Proto => "tcp",
Type => SOCK_STREAM
) or die "Couldn't connect to $remote_host:$remote_port : $@\n";
my $mode = 'read';
$mode = 'write' if $count % 5 == 0;
my $data = '-';
if ($mode eq 'write') {
$data = "$count," x 9 . $count;
}
threads->create('data_out', $server, $mode, $count, $data);
}
while (threads->list()) {
foreach my $thread (threads->list(threads::joinable)) {
$thread->join;
}
}
sleep(1);
sub data_out {
my $socket = shift;
my $mode = shift;
my $count = shift;
my $data = shift;
print $socket "$mode:$count:$data\n";
print $socket "finish\n";
while (my $line = <$socket>) {
chomp($line);
last if $line eq 'finish';
print "client $count get : $line\n";
}
close $socket;
print "client $count finished\n";
}
--
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 211.72.195.107
1F:→ kornelius:请爱用 POE :) 04/28 09:51
2F:→ tonini:POE最大的好处是甚麽呢?? 04/28 11:16
4F:→ kornelius:最显着的好处,threads 间 share 资料不是这麽方便 04/28 15:20
5F:→ kornelius:然而 POE 可利用 HEAP 直接在不同 event 里头分享物件 04/28 15:21
6F:→ kornelius:也可在不同 process 间 share objects 04/28 15:21