在 perl 中开始客户端服务器编程的最佳方法?
Best approach to start client server programming in perl?
我需要用 perl 编写客户端服务器应用程序。许多客户端将发送请求并通过服务器进行处理。
开发此类客户端服务器应用程序的最佳方法是什么。我在网上搜索并发现 LWP 和 IO::Socket 是可能的竞争者。
处理多个客户端的最佳方法是什么?这是为了分叉单独的进程还是使用线程来处理许多客户端。
这是我第一次在 perl 上进行客户端-服务器编程,所以很困惑。
好的,所以 - 处理多个并发客户端的问题是您需要处理异步传入数据。通常 - 从套接字(或文件句柄)读取是一种阻塞操作,这意味着一个客户端将 'shut out' 其他客户端。
有两种主要方法来处理这个问题——一种是以非阻塞方式从你的文件描述符中读取,使用类似IO::Select
和can_read
的东西——然后你测试你的套接字有待处理IO,处理它并重复。
来自文档:
use IO::Select;
use IO::Socket;
$lsn = IO::Socket::INET->new( Listen => 1, LocalPort => 8080 );
$sel = IO::Select->new($lsn);
while ( @ready = $sel->can_read ) {
foreach $fh (@ready) {
if ( $fh == $lsn ) {
# Create a new socket
$new = $lsn->accept;
$sel->add($new);
}
else {
# Process socket
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;
}
}
}
或者您可以使用 threads
或 forks
进行多进程 - 当您这样做时,您 'split' 您的进程,并且 运行 单独的实例,每个实例负责一个客户。
您采用哪种方法在很大程度上取决于您要实现的目标。 fork
特别适合快速高效的启动,因为它是在 POSIX 操作系统上本地实现的。然而,它对进行进程间通信 (IPC) 并不友好,因此如果您的客户需要通信……就个人而言,我不会。
如评论中所述 - 一些基本的分叉代码可以在 perlipc
中找到
线程类似于分叉 - perl 文档不推荐它,因为它不 轻量级。但它确实使线程之间的通信过程变得更加容易。如果你这样做,我建议你看看 threads
、threads::shared
和 Thread::Queue
。
使用非阻塞读取方法意味着您可以在根本不需要分叉或线程的情况下完成所有这些操作,但只有当您每次迭代都在做 'little' 事情时它才真正起作用 - 每个传入的客户端都会在处理下一个时停止,这可能意味着更多的延迟。 (虽然这可能无关紧要)。
Perlmonks 有更多不同客户端类型的示例:http://www.perlmonks.org/?node_id=436988
我需要用 perl 编写客户端服务器应用程序。许多客户端将发送请求并通过服务器进行处理。
开发此类客户端服务器应用程序的最佳方法是什么。我在网上搜索并发现 LWP 和 IO::Socket 是可能的竞争者。
处理多个客户端的最佳方法是什么?这是为了分叉单独的进程还是使用线程来处理许多客户端。
这是我第一次在 perl 上进行客户端-服务器编程,所以很困惑。
好的,所以 - 处理多个并发客户端的问题是您需要处理异步传入数据。通常 - 从套接字(或文件句柄)读取是一种阻塞操作,这意味着一个客户端将 'shut out' 其他客户端。
有两种主要方法来处理这个问题——一种是以非阻塞方式从你的文件描述符中读取,使用类似IO::Select
和can_read
的东西——然后你测试你的套接字有待处理IO,处理它并重复。
来自文档:
use IO::Select;
use IO::Socket;
$lsn = IO::Socket::INET->new( Listen => 1, LocalPort => 8080 );
$sel = IO::Select->new($lsn);
while ( @ready = $sel->can_read ) {
foreach $fh (@ready) {
if ( $fh == $lsn ) {
# Create a new socket
$new = $lsn->accept;
$sel->add($new);
}
else {
# Process socket
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;
}
}
}
或者您可以使用 threads
或 forks
进行多进程 - 当您这样做时,您 'split' 您的进程,并且 运行 单独的实例,每个实例负责一个客户。
您采用哪种方法在很大程度上取决于您要实现的目标。 fork
特别适合快速高效的启动,因为它是在 POSIX 操作系统上本地实现的。然而,它对进行进程间通信 (IPC) 并不友好,因此如果您的客户需要通信……就个人而言,我不会。
如评论中所述 - 一些基本的分叉代码可以在 perlipc
线程类似于分叉 - perl 文档不推荐它,因为它不 轻量级。但它确实使线程之间的通信过程变得更加容易。如果你这样做,我建议你看看 threads
、threads::shared
和 Thread::Queue
。
使用非阻塞读取方法意味着您可以在根本不需要分叉或线程的情况下完成所有这些操作,但只有当您每次迭代都在做 'little' 事情时它才真正起作用 - 每个传入的客户端都会在处理下一个时停止,这可能意味着更多的延迟。 (虽然这可能无关紧要)。
Perlmonks 有更多不同客户端类型的示例:http://www.perlmonks.org/?node_id=436988