在perl socket编程中如何从客户端发送数据并从服务器接收数据

时间:2016-12-01 16:06:21

标签: perl sockets

我正在使用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: $!";

1 个答案:

答案 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。相关模块的文档也提供了大量信息。