Re: [問題] 請問一下Server-Client的問題
前文吃光光
在經過友人的鼎力相助之後~終於產出了這個程式
我的貢獻度應該有~~~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
→
04/28 09:51, , 1F
04/28 09:51, 1F
→
04/28 11:16, , 2F
04/28 11:16, 2F
→
04/28 15:20, , 3F
04/28 15:20, 3F
→
04/28 15:20, , 4F
04/28 15:20, 4F
→
04/28 15:21, , 5F
04/28 15:21, 5F
→
04/28 15:21, , 6F
04/28 15:21, 6F
討論串 (同標題文章)
完整討論串 (本文為第 3 之 3 篇):
Perl 近期熱門文章
PTT數位生活區 即時熱門文章