[已解决](Socket) 一个client连接多个server 断开一个server client莫名终止

[已解决](Socket) 一个client连接多个server 断开一个server client莫名终止

程序目的描述

一个客户端程序同时连接多个服务器端。

问题描述

当一个服务器端断开后,客户端会莫名终止。

调试信息

服务器端终端 (启动server)

QUOTE:
[root@host test]# ./server.pl 1 &
[1] 9740
[root@host test]# ./server.pl 2 &
[2] 9753
[root@host test]# ./server.pl 3 &
[3] 9762

客户端终端 (正常)

QUOTE:
[root@host test]# ./client.pl
a
a -- host:1
a -- host:3
a -- host:2
...
f
f -- host:1
f -- host:3
f -- host:2

服务器端终端 (杀掉一个)

QUOTE:
[root@host test]# kill -9 9762

客户端终端 (g部分是正确的,可再输入就直接退出了)

QUOTE:
g
g -- host:1
g -- host:2
h
[root@host test]#

退出的位置

client.pl 中的 $servers{$one}->send($cmd . $EOL, 0);

以下是测试代码

#!/usr/bin/perl


#

# 客户端代码

#

# 文件名 client.pl

# 用法 ./client.pl

#


use strict;
use warnings;
use IO::Socket;

my $EOL = "\x0D\x0A";

my %servers = ();
my @myArray = (1..3);
foreach my $one (@myArray) {
        my $temp = IO::Socket::INET->new(
                Proto           => "tcp",
                PeerAddr        => '127.1',
                PeerPort        => 11100 + $one,
                Reuse           => 1
        );

        $servers{$one} = $temp if defined($temp);
}

while (1) {
        my $cmd = <STDIN>;

        $cmd =~ s/^\s*|\s*$//g;

        last if $cmd =~ m/^(exit|quit)$/;

        foreach my $one (keys %servers) {
                $servers{$one}->send($cmd . $EOL, 0);
        }

        foreach my $one (keys %servers) {
                defined(my $result = readline($servers{$one})) or next;

                print $result;
        }
}

foreach my $one (keys %servers) {
        close($servers{$one});
}



#!/usr/bin/perl


#

# 服务器端代码

#

# 文件名 server.pl

# 用法 ./server.pl 服务器编号

#


use strict;
use warnings;
use IO::Socket;

my $EOL = "\x0D\x0A";

my $server = IO::Socket::INET->new(
        Proto           => "tcp",
        LocalAddr       => '127.1',
        LocalPort       => 11100 + $ARGV[0],
        Reuse           => 1
);

$server->bind('local');
$server->listen();

while (1) {
        my $client = $server->accept();

        while (1) {
                defined(my $result = readline($client)) or last;

                $result =~ s/^\s*|\s*$//g;

                $result .= " -- host:$ARGV[0]" . $EOL;

                print $result;

                $client->send($result, 0);
        }

        close ($client);
}

close($server);


1,精心设计你的协议,以避免接收到 SIGPIPE,
或者,更合理的做法:
2,$SIG{PIPE} = sub {};

谢谢