收藏 分享(赏)

用Perl语言进行Socket编程.doc

上传人:11xg27ws 文档编号:7842284 上传时间:2019-05-27 格式:DOC 页数:15 大小:44.50KB
下载 相关 举报
用Perl语言进行Socket编程.doc_第1页
第1页 / 共15页
用Perl语言进行Socket编程.doc_第2页
第2页 / 共15页
用Perl语言进行Socket编程.doc_第3页
第3页 / 共15页
用Perl语言进行Socket编程.doc_第4页
第4页 / 共15页
用Perl语言进行Socket编程.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、用 Perl 语言进行 Socket 编程网络编程是一门神秘且复杂的艺术,当然也十分有趣。Perl 语言提供了丰富的 TCP/IP 网络函数,所有这些函数都直接来源于 C 语言的 socket 库函数. 由于 Perl 语言和 C 语言的 socket 库函数在型式和使用方法上都是一样的,因此会使用Perl 语言进行 Socket 编程, 当然也就会使用 C 语言进行 Socket 编程. 下面是 Perl 语言中有关的 socket 库函数列表:一。函数原型 使用说明 socket()socket()系统调用为客户机或服务器创建一个套接字,套接字函数在如下定义:#include#includ

2、eint socket(int family, int type, int protocol) 在 Linux 中 family=AF_UNIX.type 可以是 SOCK_STREAM 它是可靠的虽然通讯速度较慢,也可以是 SOCK_DGRAM 它通讯速度较快但不可靠 .如果 type=SOCK_STREAM 那么 protocol=IPPROTO_TCP.如果 type=SOCK_DGRAM 那么 protocol=IPPROTO_UDP.如果出错,函数将返回-1.否则返回一个套接字描述符你可以在程序后面的调用中通过套接字描述符使用这个套接字.套接字创建时没有指定名字.客户机用套接字的名字

3、读写它.这就是如下绑定函数所要做之事.listen()listen()系统调用被服务器所使用.下面有它的定义:#include#includeint listen(int sockfd, int backlog);sockfd 是套接字描述符.backlog 是在一时间内尚未被决定是否拒绝的连接的号码.一般使用标准值 5.如发生错误则返回值小于 1.如果这个调用成功,你就已经可以接受连接了.setsockopt()和 getsockopt()Linux 所提供的 socket 库含有一个错误 (bug).此错误表现为你不能为一个套接字重新启用同一个端口号,即使在你正常关闭该套接字以后.例如,比

4、方说,你编写一个服务器在一个套接字上等待的程序.服务器打开套接字并在其上侦听是没有问题的.无论如何,总有一些原因( 不管是正常还是非正常的结束程序) 使你的程序需要重新启动.然而重启动后你就不能把它绑定在原来那个端口上了.从 bind()系统调用返回的错误代码总是报告说你试图连接的端口已经被别的进程所绑定.问题就是 Linux 内核在一个绑定套接字的进程结束后从不把端口标记为未用.在大多数 UNIX 系统中,端口可以被一个进程重复使用,甚至可以被其它进程使用.在 Linux 中绕开这个问题的办法是,但套接字已经打开但尚未有连接的时候用 setsockopt()系统调用在其上设定选项(optio

5、ns).setsockopt()调用设置选项而 getsockopt()从给定的套接字取得选项.这里是这些调用的语法:#include#includeint getsockopt(int sockfd, int level, int name, char *value, int *optlen)int setsockopt(int sockfd, int level, int name, char *value, int *optlen)sockfd 必须是一个已打开的套接字 .level 是函数所使用的协议标准(protocol level)(TCP/IP协议使用 IPPROTO_TCP,套

6、接字标准的选项实用 SOL_SOCKET),选项的名称(name)在套接字说明书中(man page)有详细说明.*value 指向为 getsockopt()函数所获取的值或setsockopt()函数所设置的值的地址.optlen 指针指向一个整数,该整数包含参数以字节计算的长度.其值被 getsockopt()设置且其值必须被程序员设定当使用一个经由 setsockopt().选项的所有细节可以在使用手册中 setsockopt 的第二节(setsockopt(2)找到.现在我们再回到 Linux 的错误上来.当你打开一个套接字时必须同时用下面的代码段来调用 setsockopt()函数

7、:#ifdef LINUXopt = 1; len = sizeof(opt);setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, #endif只有当你想让程序不光是在 Linux 系统下使用时,#ifdef 和#endif 描述才是必须的.有些 UNIX 系统可能不支持或不需要 SO_REUSEADDR 标志.sendto()recvfrom()recvfrom()系统调用是这样定义的:#include #include int recvfrom(int sockfd,const void *message_, /* the pointer to messa

8、ge */int length, /* of message */unsigned int flags, /* of routing, leave 0 */const struct sockaddr * client, /* where to send it */int length ); /* of sockaddr */如果一个信息大得缓冲区都放不下,那么附加信息将被砍掉.该调用可以立即返回,也可以永久的等待.这取决于你把 flags 设置成什么类型.你甚至可以设置超时(timeout)值.在说明书(man pages)中可以找到 recvfrom 的更多信息.accept(NEWSOCK

9、ET,GENERICSOCKET) 接受请求的 socket 连接.如果成功,则返回压缩形式的网络地址;否则返回 FALSE. 范例: if (!$Connect = accept(NEW,HANDLE) die “Connection failed: $!“; bind(SOCKET,NAME) 建立 NAME 与 SOCKET 的绑定,其中 NAME 应该是对应 socket正确类型的压缩地址. 如果成功,则返回真;否则返回假.在使用 socket 进行网络编程时 ,这一函数十分重要 ,因为它建立了 socket 句柄与网络上某个地址的关联. 范例: bind(SH,$SocketAddr

10、ess);connect(SOCKET,NAME) 试图与已经调用了 accept()函数并等待建立连接的另外一个进程进行对话. connect()调用被在面向连接的系统中客户机连接服务器时使用.connect()调用必须被用在bind()调用之后.如果成功,则返回真;否则返回假.NAME 应该是对应 SOCKET 句柄正确类型的压缩地址 范例: connect(SOCK,$address) | die “Cant connect with remote host: $!“; gethostbyaddr(ADDRESS,TYPE) 将压缩形式的网络地址转换为更易于人阅读理解的名字与地址. 当只

11、知道主机的 IP 地址时,可以使用本函数查询主机名及其他网络信息.它返回一个列表,包含如下信息: ($name, $alias, $addrtype, $length, $address) 其中, $name 是与 IP 地址对应的主机名, $alias 是对应$name 的其他别名, $addrtype 是网络地址的类型, $length 是地址的长度, 而$address 则是压缩形式 IP 地址的列表. 二。范例: $PackedAddress = pack(“C4“, $IPAddr); ($name, $alias, $addrtype, $length, $address) =ge

12、thostbyaddr($PackedAddress,2); gethostbyname(NAME) 与上面的 gethostbyaddr()函数类似,不过在这里主机名是作为参数.返回的信息格式完全相同. 范例: $Host = ““; ($name, $alias, $addrtype, $length, $address) =gethostbyname($Host); IP = unpack(“C4“,$address0); $HostIP = join(“.“, IP);验证邮箱密码的程序的原码下面的代码在两种操作系统下对 和 两个 POP3 服务器严格测试, 证明是成功的. 第一种

13、: 操作系统:Windows 98 中文版 WWW 服务器:Apache 1.3.9 for Win Perl 解释器:ActiveState Tool Corp 的 Perl for Win32 , version 5.005_03 built for MSWin32-x86-object 第二种: 操作系统:Red Hat Linux 6.1 WWW 服务器:Apache 1.3.6 for Linux Perl 解释器:version 5.005_03 built for i386-linux 下一页是详细程序#!/usr/bin/perl # test.pl #Author homep

14、age: http:/ use strict; use Socket; my $pop3server = ““; my $port = 110; $|=1; print “Content-type: text/html“; print “POP3“; print “; my ($a,$name,$aliases,$proto,$type,$len,$thataddr,$thisaddr,$i); my $AF_INET = 2; my $SOCK_STREAM = 1; my $sockaddr = “S n a4 x8“; ($name,$aliases,$proto) = getproto

15、byname(“tcp“); ($name,$aliases,$port) = getservbyname($port,“tcp“) unless $port = /d+$/; ($name,$aliases,$type,$len,$thataddr) = gethostbyname($pop3server); my $this = pack($sockaddr, $AF_INET, 12345, $thisaddr); my $that = pack($sockaddr, $AF_INET, $port, $thataddr); my $mysocket = socket(S, $AF_IN

16、ET, $SOCK_STREAM, $proto); if ($mysocket) else print “不能打开 socket: $!“; exit(0); my $mybind = bind(S, $this); if ($mybind) else print “无法绑定!: $!“; exit(0); my $myconnect = connect(S,$that); if ($myconnect) else print “连接错误: $!“; exit(0); my $BUF = “; my $SenderIP = recv(S, $BUF, 596,0); if ($SenderI

17、P) else print “接收错误: $!“; exit(0); if (substr($BUF,0,3) eq “+OK“) else print “POP3 服务器出错!“; exit(0); my $BUFFER = “USER zhangsan“; $BUFFER .= chr(13); $BUFFER .= chr(10); my $SENVAL = send(S, $BUFFER,0); if ($SENVAL) else print “发送错误: $!“; exit(0); my $BUF = “; my $SenderIP = recv(S, $BUF, 4096,0);

18、if ($SenderIP) else print “接收错误: $!“; exit(0); if (substr($BUF,0,3) eq “+OK“) else print “无此帐号!“; exit(0); $BUFFER = “PASS 12345678“; $BUFFER .= chr(13); $BUFFER .= chr(10); my $SENVAL = send(S, $BUFFER,0); if ($SENVAL) else print “发送错误: $!“; exit(0); $BUF = “; my $SenderIP = recv(S, $BUF, 196, 0);

19、if ($SenderIP) else print “接收错误: $!“; exit(0); if (substr($BUF,0,3) eq “+OK“) else print “密码错误!“; exit(0); print 密码是正确的! 本程序版权归菜瓜乐园 EOF exit(0);三。程序说明面向套接字协议的服务器端 #include #include #include #include #define MY_PORT 6545main(int argc, char *argv)int sockfd, newfd;int cpid; /* child id */struct sockad

20、dr_in servaddr;struct sockaddr_in clientInfo;if (sockfd = socket(AF_INET, SOCK_STREAM, 0) #include #include #include #define MY_PORT 6545#define MY_HOST_ADDR “204.25.13.1“int getServerSocketId()int fd, len;struct sockaddr_in unix_addr;/* create a Unix domain stream socket */if ( (fd = socket(AF_UNIX

21、, SOCK_STREAM, 0) #include #include #include #define MY_PORT 6545#define MAXM 4096char mesgMAXM;main(int argc, char *argv)int sockfd, newfd;int cpid; /* child id */struct sockaddr_in servaddr;struct sockaddr_in clientInfo;if (sockfd = socket(AF_INET, SOCK_STREAM, 0) #include int sendto(int sockfd,const void *message_, /* the pointer to message */int length, /* of message */unsigned int type, /* of routing, leave 0 */const struct sockaddr * client, /* where to send it */int length ); /* of sockaddr */注意:如果你使用的是 BSD 系统,请使用 sendto()系统调用,不要使用 sendmsg(),因为 sendto()性能更好.如出错则返回-1,不过仅能检查出本地错误.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报