我正在使用Socket模块在Perl中执行套接字编程。现在我想从客户端发送一个数据并从服务器端接收它。我将如何实现这一目标。请帮忙。
在我使用的代码中给出
服务器
#!/usr/bin/perl -w
# Filename : server.pl
use strict;
use IO::Socket;
use Socket;
use Sys::Hostname;
use constant BUFSIZE => 1024;
# use port 7890 as default
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost"; # Host IP running the server
# create a socket, make it reusable
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "Can't open socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
or die "Can't set socket option to SO_REUSEADDR $!\n";
# bind to a port, then listen
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "Can't bind to port $port! \n";
listen(SOCKET, 5) or die "listen: $!";
print "SERVER started on port $port\n";
# accepting a connection
my $client_addr;
my $val = 100;
while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
# send them a message, close connection
my $name = gethostbyaddr($client_addr, AF_INET );
print NEW_SOCKET "Smile from the server";
print NEW_SOCKET $val;
print "Connection recieved from $name\n";
close NEW_SOCKET;
}
客户端
#!/usr/bin/perl -w
# Filename : client.pl
use strict;
use IO::Socket;
use Socket;
use Sys::Hostname;
use constant BUFSIZE => 1024;
# initialize host and port
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost"; # Host IP running the server
# create the socket, connect to the port
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
or die "Can't create a socket $!\n";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "Can't connect to port $port! \n";
my $line;
my $req = 1000;
while ($line = <SOCKET>) {
print "$line\n";
}
close SOCKET or die "close: $!";
答案 0 :(得分:1)
这是一个基本的例子。下面的代码会增加您所拥有的代码,但请注意,模块IO::Socket::IP或核心IO::Socket::INET比您使用的较低级别调用更容易。
您的代码的唯一更改(除了以下所示)是从SOCKET
到词汇my $socket
,现有声明在while
条件内移动。
每个服务器 - 客户端系统都需要一个协议,一个消息交换方式的安排。在这里,一旦客户端连接服务器发送消息,然后他们交换单个打印。
<强> server.pl 强>
# ... code from the question, with $socket instead of SOCKET
use IO::Handle; # for autoflush
while (my $client_addr = accept(my $new_socket, $socket))
{
$new_socket->autoflush;
my $name = gethostbyaddr($client_addr, AF_INET );
print "Connection received from $name\n";
print $new_socket "Smile from the server\n";
while (my $recd = <$new_socket>) {
chomp $recd;
print "Got from client: $recd\n";
print $new_socket "Response from server to |$recd|\n";
}
close $new_socket;
}
不是加载IO::Handle
,而是可以使用select使句柄变热(autoflush)。
client.pl
我添加一个计数器$cnt
来模拟一些导致条件突破的处理。
# ... same as in question, except for $socket instead of SOCKET
use IO::Handle;
$socket->autoflush;
my $cnt = 0;
while (my $line = <$socket>) {
chomp $line;
print "Got from server: $line\n";
last if ++$cnt > 3; # made up condition to quit
print $socket "Hello from client ($cnt)\n";
}
close $socket or die "close: $!";
这表现得如预期。客户端在三条消息之后退出,服务器保持等待。如果您希望在简单的打印和读取之后确实只写一次while
循环。
交流可能要复杂得多,请参阅最后链接的perlipc示例。
一些评论。我记得会添加更多内容。
使用上述模块可以更轻松地实现这一目标
任何刷新故障都可能导致死锁,一方写入并等待阅读,另一方没有消息仍然位于管道中,因此, ,等着阅读
检查一切。为简洁起见,省略了所有检查
use warnings;
优于-w
切换。请参阅discussion on warnings page
这只是为了回答如何在之间启用的问题。一个很好的学习资源是perlipc,它也有一个full example。相关模块的文档也提供了大量信息。