📄 socket.txt
字号:
socket
你可以从socket读出东西,或写入东西。 Socket是一种表示网络连接的双向文件句柄。和一般以open开启的文件不同的是, socket建立的方式是通过低层socket函数。
让我们以电话为例。当你打进某间公司的交换机,你可以按下某些代表号码,转到某个部门。把计算机上执行的各个服务想成一间大公司的部门,有时某个服务有不同的名称,如http和www,但只有一个号码,如80。这个和服务名称相关的数字就是它的port。Perl的函数 getservname与getservbyport可以根据提供的port号码寻找服务名称,反之亦然。表C-1列出一些标准的TCP服务与它们的port号码。
表C-1标准的TCP服务与其port号码
服务 Port 作用
echo 7 接受所有输入以及回应
discard 9 接受所有东西但什么都不做
daytime 13 传回目前日期与时间
ftp 21 文件传输
telnet 23 交互的telnet会话
smtp 25 MailerDaemon简单邮件传输的协议
time 37 传回从1900算起的秒数(以二进制代码)
http 80 WWW server
nntp 119 News server
虽然 sockets原始是在BerkeleyUnix版本上发展起来的,但目前几乎所有的操作系统都已加入这类功能。直接利用 sockets函数是有点低阶,我们建议你用 IO::Socket(IO:Socket是Perl5.004发行版中的一个标准部分)模块。
简单的客户端程序
我们的客户端程序提供一个挺无聊的功能,就是用一行显示远程服务器的目前时间,显示之后结束连接。
下面是程序代码:
use IO::Socket;
$remote=IO::Socket::INET->new(
Proto=>"tcp",
PeerAddr=>"localhost",
PeerPort=>"daytime(13)",
)
or die "can not connect to daytime port at localhost";
while(<$remote>){print;}
程序执行应该会出现下面这样的文字:
Thu May 8 11:57:15 1998
下面是new里面参数的意义:
Proto
所用的协议(protocol)。在我们的例子里,返回的socket handle会接上一个 TCP socket,因为我们要的是一个数据流(stream)导向的连接。意思是说,一个行为模式类似一般普通文件的东西。并非所有的socket都是这个样子。例如, UDP协议可建立一个数据报(datagram) socket,进行信息传递。
PeerAddr
远方服务器主机的名称或 Internet地址。我们可以指定一个较长的名称如www.perl.com,或一个地址如204.148.40.9。为了说明起见,我们选用特别的主机名称 hostname,这是你目前执行的主机。相对的主机地址是127.0.0.1,如果你喜欢的话也可以用。
PeerPort
我们想连线的服务名称或Port号码。当然,我们可以直接通过系统的服务文件取得(Unix 中是 /etc/services),但为了安全起见,我们还是指定port号码(13)。
注意,new的传回值在while循环中被当作一个文件句柄。这个例子是一个间接的文件句柄,它是一个包含文件句柄的标量变量。你可以把它当作一般的文件句柄使用。例如,你可以从它读进一行数据:
$line=<$handle>;
或是读进剩下的所有行:
@line=<$handle>;
或是送进一行数据给它:
print $handle "some data\n";
Webget客户端程序
下面这个程序会和远程服务器连接,从上面取得一些文件。当然,这个程序比上一个好玩多了,因为它在取得数据之前会先送出一些东西。
use IO::Socket;
unless (@ARGV >1) {die "usage: $0 host document ...";}
$host=shift(@ARGV);
foreach $document (@ARGV){
$remote=IO::Socket::INET->new(
Proto=>"tcp",
PeerAddr=>$host,
PeerPort=>"http(80)",
);
unless ($remote) { die "cannot connect to http daemon on $host";}
$remote->autoflush(1);
print $remote "GET $document HTTP/1.0\n\n";
while(<$remote>){print;}
close $remote;
}
假设处理http服务的Web服务器是通过标准的port80。如果对方是利用不同的port,例如8080,你就应该指定 PeerPort=>8080。应该通过autoflush功能,否则我们的输出会溢出(buffer up)缓冲区。
连上服务器只是过程的第一步:建立连接之后,你必须以服务器的语言和它交谈。网络上的每一种服务器都有它专用的语言。我们一开始送给服务器的是GET字符串,这是HTTP认识的语言。在我们的例子中,我们只是单纯的请求指定的文件。没错,我们每次请求一份文件都会重新建立连接,就算同一台主机也没差别,但HTTP就是这么麻烦(新版本却览器会请求服务器让连接维持久一点,但服务器不见得要答应这些请求)。
如果你想研究这个程序的完整版本,请参考CPAN中 LWP模组的lwprequest程序。
你应该看看 Win32::Internet扩充模块,它让你充分利用 HTTP与 FTP协议。
Win32::Internet是附在1ibwin32里面, ActiveState版本也有。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -