tcp.pl
上传用户:minyiyu
上传日期:2018-12-24
资源大小:864k
文件大小:13k
- #!/usr/local/bin/perl
- package main;
- sub tcp'getostype {
- chop($_=`uname -a`);
- if ( /^SunOS/i ) {
- ($os,$host,$ver)=split(/s+/,$_);
- if ( $ver =~ /5./ ) {
- return "Solaris";
- } else {
- return "BSD";
- }
- } elsif (/^HP-UX/i) {
- return "SYSV";
- } elsif (/^AIX/i ) {
- return "AIX";
- } elsif (/^OSF1/i) {
- return "SYSV";
- }
- }
- $tcp'OS = &tcp'getostype();
- if ( $OS eq "Solaris") {
- eval 'sub SOCK_STREAM {2;}';
- eval 'sub SOCK_DGRAM {1;}';
- } else {
- eval 'sub SOCK_STREAM {1;}';
- eval 'sub SOCK_DGRAM {2;}';
- }
- eval 'sub SOCK_RAW {3;}';
- eval 'sub SOCK_RDM {4;}';
- eval 'sub SOCK_SEQPACKET {5;}';
- eval 'sub SO_DEBUG {0x0001;}';
- eval 'sub SO_ACCEPTCONN {0x0002;}';
- eval 'sub SO_REUSEADDR {0x0004;}';
- eval 'sub SO_KEEPALIVE {0x0008;}';
- eval 'sub SO_DONTROUTE {0x0010;}';
- eval 'sub SO_BROADCAST {0x0020;}';
- eval 'sub SO_USELOOPBACK {0x0040;}';
- eval 'sub SO_LINGER {0x0080;}';
- eval 'sub SO_OOBINLINE {0x0100;}';
- eval 'sub SO_DONTLINGER {(~ &SO_LINGER);}';
- eval 'sub SO_SNDBUF {0x1001;}';
- eval 'sub SO_RCVBUF {0x1002;}';
- eval 'sub SO_SNDLOWAT {0x1003;}';
- eval 'sub SO_RCVLOWAT {0x1004;}';
- eval 'sub SO_SNDTIMEO {0x1005;}';
- eval 'sub SO_RCVTIMEO {0x1006;}';
- eval 'sub SO_ERROR {0x1007;}';
- eval 'sub SO_TYPE {0x1008;}';
- eval 'sub SOL_SOCKET {0xffff;}';
- eval 'sub AF_UNSPEC {0;}';
- eval 'sub AF_UNIX {1;}';
- eval 'sub AF_INET {2;}';
- eval 'sub AF_IMPLINK {3;}';
- eval 'sub AF_PUP {4;}';
- eval 'sub AF_CHAOS {5;}';
- eval 'sub AF_NS {6;}';
- eval 'sub AF_NBS {7;}';
- eval 'sub AF_ECMA {8;}';
- eval 'sub AF_DATAKIT {9;}';
- eval 'sub AF_CCITT {10;}';
- eval 'sub AF_SNA {11;}';
- eval 'sub AF_DECnet {12;}';
- eval 'sub AF_DLI {13;}';
- eval 'sub AF_LAT {14;}';
- eval 'sub AF_HYLINK {15;}';
- eval 'sub AF_APPLETALK {16;}';
- eval 'sub AF_NIT {17;}';
- eval 'sub AF_802 {18;}';
- eval 'sub AF_OSI {19;}';
- eval 'sub AF_X25 {20;}';
- eval 'sub AF_OSINET {21;}';
- eval 'sub AF_GOSIP {22;}';
- eval 'sub AF_MAX {21;}';
- eval 'sub PF_UNSPEC { &AF_UNSPEC;}';
- eval 'sub PF_UNIX { &AF_UNIX;}';
- eval 'sub PF_INET { &AF_INET;}';
- eval 'sub PF_IMPLINK { &AF_IMPLINK;}';
- eval 'sub PF_PUP { &AF_PUP;}';
- eval 'sub PF_CHAOS { &AF_CHAOS;}';
- eval 'sub PF_NS { &AF_NS;}';
- eval 'sub PF_NBS { &AF_NBS;}';
- eval 'sub PF_ECMA { &AF_ECMA;}';
- eval 'sub PF_DATAKIT { &AF_DATAKIT;}';
- eval 'sub PF_CCITT { &AF_CCITT;}';
- eval 'sub PF_SNA { &AF_SNA;}';
- eval 'sub PF_DECnet { &AF_DECnet;}';
- eval 'sub PF_DLI { &AF_DLI;}';
- eval 'sub PF_LAT { &AF_LAT;}';
- eval 'sub PF_HYLINK { &AF_HYLINK;}';
- eval 'sub PF_APPLETALK { &AF_APPLETALK;}';
- eval 'sub PF_NIT { &AF_NIT;}';
- eval 'sub PF_802 { &AF_802;}';
- eval 'sub PF_OSI { &AF_OSI;}';
- eval 'sub PF_X25 { &AF_X25;}';
- eval 'sub PF_OSINET { &AF_OSINET;}';
- eval 'sub PF_GOSIP { &AF_GOSIP;}';
- eval 'sub PF_MAX { &AF_MAX;}';
- eval 'sub SOMAXCONN {5;}';
- eval 'sub MSG_OOB {0x1;}';
- eval 'sub MSG_PEEK {0x2;}';
- eval 'sub MSG_DONTROUTE {0x4;}';
- eval 'sub MSG_MAXIOVLEN {16;}';
- #package tcp;
- $defaultport = 'nntp';
- $defaultserver = 'ccsun35.csie.nctu.edu.tw.';
- $ENV{'PATH'}='/bin:/usr/ucb:/usr/etc';
- # The Internet TCP client algorithm
- # 1. Find the IP address and protocol port number of the server
- # with which communication is desired. (gethostbyname,getservbyname)
- # 2. Allocate a socket. (socket)
- # 3. Specify that the connection needs an arbitary, unsed protocol
- # port on the local machine, and allow TCP to choose one. (bind)
- # 4. Connect the socket to the server. (connect)
- # 5. Communicate with the server using the application-level protocol
- # (this usually involves sending requests and awaiting replies)
- # 6. close the connection.
- #
- # reference:
- # socket addr, internet style structure for Sun-OS
- # include <netinet/in.h>
- # struct sockaddr_in {
- # short sin_family;
- # u_short sin_port;
- # struct in_addr sin_addr;
- # char sin_zero[8];
- # }
- # ( 'S n a4 x8' template for perl pack)
- # Usage
- # &tcpinetclient(FILEHANDLE[,hostname,portno]);
- # for example,
- # &tcpinetclient(NNTP,'news.csie.nctu.edu.tw','nntp');
- # print NNTP "helprn";
- # $_ = <NNTP>;
- # print;
- sub main'tcpinetclient {
- local(*S,$server,$port)=@_;
- $port = $defaultport unless $port;
- $server = $defaultserver unless $server;
- local($hostname);
- chop($hostname = `hostname`);
- local($sockaddr)= 'S n a4 x8';
- local($name,$aliases,$proto)=getprotobyname('tcp');
- local($name,$aliases,$port)=getservbyname($port,'tcp')
- unless $port =~ /^d+$/;
- # print "port number in tcpinetclient $portn";
- local($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
- local($name, $aliases, $type, $len, $thataddr) = gethostbyname($server);
- socket(S, &main'PF_INET, &main'SOCK_STREAM, $proto) || die "socket: $!";
- local($this) = pack($sockaddr, &main'AF_INET, 0, $thisaddr);
- # accept connect from any port (0)
- local($that) = pack($sockaddr, &main'AF_INET, $port, $thataddr);
- # bind(S, $this) || die "bind to $hostname: $!";
- connect(S, $that) || die "connect to $port: $!";
- select(S); $| = 1; select(STDOUT);
- 1;
- }
- # reference: socket for unix domain in Sun-OS
- # include <socket.h>
- # struct sockaddr {
- # u_short sa_family;
- # char sa_data[14];
- # }
- # ('S a14' perl template for perl)
- # usage
- # &tcpunixclient(FILEHANDLE,path);
- # for example,
- # &tcpunixclient(LOCAL,"/tmp/unixsock$$");
- #$defaultpath="/tmp/unixsock$$";
- $defaultpath='/tmp/sample';
- # only 14 chars can be used
- sub main'tcpunixclient {
- local(*S,$path)=@_;
- $path = $defaultpath unless $path;
- local($sockaddr)= 'S a14';
- socket(S, &PF_UNIX, &SOCK_STREAM, 0) || die "socket: $!";
- $that = pack($sockaddr, &AF_INET, $path);
- connect(S, $that) || die "connect to $path: $!";
- select(S); $| = 1; select(STDOUT);
- 1;
- }
- # o Interactive, Connection-Orientd Server
- # o Interactive, Connectionless Server
- # o Concurrent, Connectionless Server
- # server repeatedly call "recvform" and let slave use "sendto"
- # to reply the client.
- # o concurrent, connection-oriented server algorithm
- # Master 1. Create a socket and bind to the well-known address
- # for the service being offered. Leave the socket unconnected
- # (socket,bind)
- # Master 2. Place the socket in passive mode, makeing it ready for used
- # by a server. (listen)
- # Master 3. Repeatedly call accept to receive the next request from
- # a client, and create a new slave process to handle the
- # response. (accept)
- # Slave 1. Receive a connection request (i.e., socket for the connection)
- # upon creation.
- # Slave 2. Interact with the client using the connection: read request(s)
- # and send back response(s).
- # Slave 3. Close the connection and exit. The slave process exits
- # after handling all requests from one client.
- #
- # Usage
- # &tcpinetserver([port-no,service-routine,before,each]);
- # for example
- # &tcpinetserver(1234,'simple_service');
- #
- $defaultserverport=1234;
- $defaultserviceroutine="simple_service";
- sub simple_service {
- local(*S)=@_;
- while (<S>) {
- if (/quit/) {
- return(0);
- } elsif (/help/) {
- print S <<"EOF";
- This is a simple sample server r
- available command r
- help quit r
- EOF
- } else {
- print S "Unknown commandrn";
- }
- }
- }
- sub reapchild {
- while (waitpid(-1,&WNOHANG|&WUNTRACED)>0) {
- # print "reapchildn";
- # while (waitpid(-1,&WNOHANG)>0) {
- # print "reaping childn";
- next;
- }
- 1;
- }
- #sub reapchild {
- # while (1) {
- # $pid = waitpid(-1,&WNOHANG);
- # last if ($pid < 1);
- # }
- #}
- sub dokill {
- kill 9,0;
- }
- sub main'tcpinetserver {
- local($port,$service,$before,$each)=@_;
- if ($port != 0) {
- $port = $defaultserverport unless $port;
- }
- $service = $defaultserviceroutine unless $service;
- local($sockaddr)= 'S n a4 x8';
- local($name,$aliases,$proto)=getprotobyname('tcp');
- local($name,$aliases,$port)=getservbyname($port,'tcp')
- unless $port =~ /^d+$/;
- local(*S,*NS);
- chdir("/");
- socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
- setsockopt(S,main'SOL_SOCKET,main'SO_REUSEADDR,1);
- setsockopt(S,main'SOL_SOCKET,main'SO_LINGER,0);
- if ($port == 0) {
- local($hostname);
- chop($hostname = `hostname`);
- local($name, $aliases, $type, $len, $thisaddr) = gethostbyname($hostname);
- } else {
- $thisaddr = "