perl socket编程 [perl]

使用PERL SOCKET API首先需要载入SOCKET模块。

use Socket;

===================================

socket(文件句柄,AF_INET,数据类型,协议类型);

#建立套接字

文件句柄随便找个词就可以了。

AF_INET为域类型,也可以写为PF_INET。

数据类型,通常用有两种:SOCK_STREAM、SOCK_DGRAM。

协议类型,可以用协议号代替,EGP—8、HMP—20、ICMP—1、RAW—255、RDP—27、RVD—66、TCP—6、UDP—17、XNS-IDP—22、

其他—22、ALL—0;也可以用getprotobyname()函数作此参数。

例子:socket(SOCK,AF_INET,SOCK_STREAM,getprotobyname(’tcp’));

语柄为SOCK,套接字以TCP方式传输。

socket(SS,AF_INET,SOCK_DGRAM,17);

语柄为SS,套接字以UDP方式传输。

=========================================

connect(文件句柄,sockaddr_in结构体);

#连接主机

———————————————–

sockaddr_in结构体:

$address=inet_aton(主机地址);

$port=端口号;

$result=sockaddr_in($port,$address);

#上面的$result就是sockaddr_in结构体,实例:

$address=inet_aton(127.0.0.1);

$port=80;

$result=sockaddr_in($port,$address);

———————————————–

例子:connect(SOCK,$result);

 

========================================

bind(套接字,sockaddr_in结构体);

#绑定服务器主机地址与端口(用于服务端)

例子:bind(SOCK,$result);

========================================

listen(套接字,等待连接最大队列数);

#设置端口状态为监听(用于服务端)

例子:listen(SOCK,10);

===========================================================

accept(远程套接字,服务端监听套接字)

#接收远程数据请求,建立连接(用于服务端)

例子:accept(SESSION,SOCK);

=======================================

close(文件句柄);

close 文件句柄;

#关闭套接字

例子:close(SOCK);

close SS;

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

说说TCP的网络活动顺序:

=======================================================

Client(客户端):

建立套接字socket()->连接到目标主机connect()->打开autoflush模式autoflush()->

I/O操作->关闭套接字close()

Server(服务器):

建立套接字socket()->绑定服务器地址与端口bind()->设置监听状态listen()->接受远程套接字accept()->

打开autoflush模式autoflush()->I/O操作->关闭套接字close()

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎

PERL SOCKET API编程实例:

附:I/O操作暂时只使用print()与符号。

==========================================

#!usr/bin/perl

#客户端

use IO::Handle; #挂起IO::Handle

use Socket; #调用SOCKET

$port=80; #连接远程主机的80端口

$host='localhost'; #使用环回地址

$packhost=inet_aton($host); #压缩IP地址

$address=sockaddr_in($port,$packhost); #压成sockaddr_in格式

socket(CLIENT,AF_INET,SOCK_STREAM,6); #套接字为CLIENT,使用TCP协议

connect(CLIENT,$address); #连接

CLIENT->autoflush(1); #开启AUTOFLUSH模式

$msg_in=; #INPUT

print "IN:$msg_in/n"; #OUTPUT

close CLIENT; #关闭套接字

exit 1; #退出程序

=========================================

#!usr/bin/perl

#服务端

use IO::Handle; #挂起IO::Handle

use Socket; #调用SOCKET

$port=80; #绑定的服务器主机端口为80

$address=sockaddr_in($port,INADDR_ANY); #压成sockaddr_in格式,使用INADDR_ANY通配符

socket(SERVER,AF_INET,SOCK_STREAM,getprotobyname('tcp')); #套接字为SERVER,使用TCP协议

bind(SERVER,$address); #绑定

listen(SERVER,10); #设置监听状态

while(1){ #进入I/O交换循环体

next unless (accept(CLIENT,SERVER));

CLIENT->autoflush(1);

print CLIENT "WHAT DO YOU WANT?/n";

close CLIENT;}

close SERVER; #关闭套接字

exit 1; #退出程序

=============================================

实例注解:

1)TCP的client与server代码中有一行’SOCK->autoflush(1);’,正常情况下下面的I/O代码是会先进入缓存,

再输出的,但加了上面的代码就可以跳过这一步直接输出了。此代码需要预先加载IO::Handle。

2)INADDR_ANY通配符的值在Socket模块中已经定义了,其值为本地网络适配的所有网络接口(包括环回地址、

广播地址、多播地址等)。

◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎

头有点痛,写到这里,下回介绍send()与recv()……..:P

[日记文]’send()’ and ‘recv’[perl_sock 2]

writer:demonalex

email:demonalex_at_dark2s.org

附接上文的某些内容,最后使用的两个C/S程序中的数据交换部分使用了PERL I/O,

现在介绍一下PERL语言分配给套接字的‘原装’网络数据交换函数:send()、recv()。

(这两个函数对UDP协议的作用很大,但对TCP来说其实只能说是等于syswrite()、sysread()。)

==========================================

字节变量=send(套接字,传送数据变量,标志参数);

send()函数用于在套接字进程中发送数据。

send()返回的值是储存所发送的字节大小值的变量;传送数据变量为传输数据的内容;

标志参数为0(默认值就可以了)。

例子:$bytes=send(SOCK,$data,0);

=======================================================

地址变量=recv(套接字,接收后的数据所储存的变量,接收数据的长度,标志参数);

recv()函数用于在套接字进程中接收数据。

recv()返回远程主机的地址变量;第二个参数为接收后的数据所储存的变量;第三个

参数为所接收数据的长度;标志参数同样为默认值0就可以了。

例子:$address=recv(SOCK,$buffer,$length,0);

===========================================

实验1

#!usr/bin/perl

#客户端

use IO::Handle;

use Socket;

$port=80;

$host='localhost';

$packhost=inet_aton($host);

$address=sockaddr_in($port,$packhost);

socket(CLIENT,AF_INET,SOCK_STREAM,6);

connect(CLIENT,$address);

CLIENT->autoflush(1);

recv(CLIENT,$msg_in,length($msg_in),0);

print "IN:$msg_in/n";

close CLIENT;

exit 1;

==========================================

#!usr/bin/perl

#服务端

use IO::Handle;

use Socket;

$port=80;

$host='localhost';

$packhost=inet_aton($host);

$address=sockaddr_in($port,$packhost);

socket(SERVER,AF_INET,SOCK_STREAM,getprotobyname('tcp'));

bind(SERVER,$address);

listen(SERVER,10);

while(1){

next unless (accept(CLIENT,SERVER));

CLIENT->autoflush(1);

$msg_out="WHAT DO YOU WANT?/n";

send(CLIENT,$msg_out,0);

close CLIENT;}

close SERVER;

exit 1;

[日记文]udp of perl socket[perl_sock 3]

writer:demonalex

email:demonalex_at_dark2s.org

继续上文谈到的send()与recv(),这次谈一下它们在udp socket中的应用以及如果使用

perl socket API来调用UDP。

先看看在UDP中的send()、recv()应用:

==============================================

字节变量=send(套接字,传送数据变量,标志参数,发送地址);

send()函数用于在套接字进程中发送数据。

send()返回的值是储存所发送的字节大小值的变量;传送数据变量为传输数据的内容;

标志参数为0(默认值就可以了);send()在udp中就多了最后一个参数,‘发送地址’,

此地址的数据形式为sockaddr_in格式,表示把第二参数‘传送数据变量’发送到此地址中。

例子:$bytes=send(SOCK,$data,0,$address);

楼上例子中的$address为sockaddr_in格式。

============================================

地址变量=recv(套接字,接收后的数据所储存的变量,接收数据的长度,标志参数);

recv()函数用于在套接字进程中接收数据。

recv()返回远程主机的地址变量;第二个参数为接收后的数据所储存的变量;第三个

参数为所接收数据的长度;标志参数同样为默认值0就可以了。

例子:$address=recv(SOCK,$buffer,$length,0);

================================================

从楼上的讲解可以知道,在UDP调用中send()比TCP调用时多了一个参数,而recv()与在TCP调用时的

使用方法完全一致。

———————————————————

UDP网络活动顺序:

Client(客户端):

建立套接字socket()->发送数据send()->接受数据recv()->关闭套接字close()

Server(服务端):

建立套接字socket()->绑定地址bind()->接受数据recv()->发送数据send()->关闭套接字close()

————————————————————-

从楼上的流程不难发现UDP中的客户端与服务端的不同之处有两点:1)服务端在建立套接字后多添了一个

绑定bind()程序,用于使客户端能分辨出服务端的网络地址与端口;2)在send()与recv()步骤上顺序倒过

来了。

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

最后可以看看例子,琢磨琢磨:

━━━━━━━━━━━━━━━━━━━━━━━━━━━

#!use/bin/perl -w

#udp client

use Socket; #导入Socket库

$host=$ARGV[0]; #第一参数为主机变量

$port=$ARGV[1]; #第二参数为端口变量

$packhost=inet_aton($host); #压缩主机地址

$address=sockaddr_in($port,$packhost); #压为sockaddr_in模式

socket(CLIENT,AF_INET,SOCK_DGRAM,17); #建立UDP套接字

send(CLIENT,”hi,body!/n”,0,$address); #向套接字发送字符串变量

recv(CLIENT,$buff,100,0); #接收数据

print”$buff/n”; #把接收后的数据打入STDOUT

close CLIENT; #关闭套接字

exit 1; #退出程序

¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

#!use/bin/perl -w

#udp server

use Socket; #导入Socket库

$localhost=sockaddr_in(4000,INADDR_ANY);#压入sockaddr_in模式,使用了全局本地压缩地址INADDR_ANY保留字

socket(SERVER,AF_INET,SOCK_DGRAM,17); #建立UDP套接字

bind(SERVER,$localhost); #绑定套接字

while(1){ #进入服务器循环体

next unless $client=recv(SERVER,$buff,100,0); #如果接收到数据就把数据压入$buff,保留远程地址在$client

chop($buff); #减去$buff最后的输入符号

print “$buff/n”; #在$buff变量打入STDOUT

send(SERVER,”$buff/n”,0,$client); #把$buff发送给客户端

}

close SERVER; #关闭套接字

exit 1; #退出程序

━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[日记文]Summary[perl_sock 4]

writer:demonalex

email:demonalex_at_dark2s.org

此文为前三篇文章的总结文。

tcp的服务端I/O结构体:

———————————————–

while(1){

next unless (accept(CLIENT,SERVER));

CLIENT->autoflush(1);

print CLIENT “WHAT DO YOU WANT?/n”;

close CLIENT;}

———————————————–

udp的服务端I/O结构体:

———————————————–

while(1){

next unless $client=recv(SERVER,$buff,100,0);

chop($buff);

print “$buff/n”;

send(SERVER,”$buff/n”,0,$client);

}

———————————————–

从上面的实例可以看出SERVER的I/O体都是循环体,有一特定条件进行循环

(我们这里用了死循环while(1)),为了就是使服务端能不停的在监听。

TCP I/O的特征就是在accept()中生成一个客户端的套接字,所有I/O操作都

在此套接字中进行,当I/O完成后,先把客户端的套接字关闭,最后才在程序

的末端部分关闭服务端的套接字。

UDP I/O的特征就是recv()部分,由于在介绍UDP的那篇文中的实例为通过UDP

把输入的数据返回到客户端的程序,在服务端中的下一步就应该调用send()了,

在send()中的最后一个参数为sockaddr_in形式地址,又因为在UDP中不能调用

accept(),所以无法得知对方的对象在哪里,只能通过recv()的返回值。recv()

的返回值刚好为对方发送数据的sockaddr_in形式地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值