zoukankan      html  css  js  c++  java
  • 42.xinetd

    xinetd

     什么是xinetd

    1、xinetd可以统一管理很多服务进程,它能够:

    绑定、侦听、和接受来对自服务器每个端口的请求
    
    有客户端访问时,调用相应的服务器程序响应
    
    节约了系统内存资源
    
    同时响应多个客户端的连接请求

    2、Windows系统没有该功能

    3、多数UNIX系统使用的是inetd实现相同的功能

    配置文件解析

    flags : 如果只指定NAMEINARGS,那么它就使参数和inetd一样地传递 
    type :  如果服务不在/etc/services中,则使用UNLISTED,否则可以忽略这一行 
    port :  如果type=UNILISTED,则在这里指定端口号 
    socket_type : 如果是TCP,使用stream;如果是UDP,使用dgram protocol :指定TCP,还是UDP
    wait : TCP设置为no。对于UDP,如果服务器连接远程主机并为不同客户端建立新的进程,则为no;如果UDP在它的端口上处理所有的信息包,
          直到它被终止,则为yes
    user : 指定程序的运行身份
    server : 服务程序的完整路径
    server_args :参数。为了和inetd兼容,flags设置为NAMEINARGS,则参数使用服务器名

     编写xinetd程序

     使用标准输入输出

    1、当使用xinetd的时候,它通过两个方法传递socket:如文件描述符0和1

    2、它们和文件描述符一样,分别代表标准输入和标准输出

    3、因为标准输出sys.stdout默认是被缓冲的,所以为了实时性,需要使用到sys.stdout.flush()函数

    4、通过这种方法,服务器端程序既可以当成网络服务器程序使用,也可以像普通的脚本程序一样执行

    #!/usr/bin/env python
    import sys
    print 'Welcome.'
    print 'Please enter a string: '
    sys.stdout.flush()
    line = sys.stdin.readline().strip()
    print 'You enterd %d characters' % len(line)

    执行结果: python ser.py

    
    Welcome.
    Please enter a string: 
    abc
    You enterd 3 characters

    配置 xinetd 服务

    编写 xinetd 服务配置文件,主要要求如下:
    1、服务器监听在 0.0.0.0 的 51423 端口上
    2、服务器采用 TCP 协议进行通信
    3、服务器以 root 身份运行
    4、服务器运行文件是/root/bin/exmaple.py

    方案
    前面所编写的服务器程序,都只能接受一个客户端的连接,如果超过一个客户端,后续的请求不得不排队等候。
    使用超级守护进程 xinetd 是解决多客户端连接的一种方式。它能够绑定、侦听、和接受来对自服务器每个端口的请求,有客户端访问时,调用相应的服务器程序响应。

    还能够同时响应多个客户端的连接请求。
    基于 xinetd 超级守护进程的服务,需要在/etc/xinetd.d/目录下创建相关的服务器配置文件

    步骤
    实现此案例需要按照如下步骤进行。
    步骤一:安装并配置 xinetd
    RHEL6 操作系统默认没有安装 xinetd,首先安装

    [root@py01 bin]# yum install -y xinetd
    [root@py01 bin]# service xinetd start
    [root@py01 bin]# chkconfig xinetd on

    步骤二:创建服务器配置文件

     
    [root@py01 bin]# vim /etc/xinetd.d/pyserver
    service pyserver #起始语句块
    {
        flags = NAMEINARGS #使参数和 inetd 一样地传递
        type = UNLISTED #如果服务不在/etc/services,指定为 UNLISTED
        port = 51423 #指定服务端口号
        socket_type = stream #使用 TCP 协议,则为 stream
        protocol = tcp
        wait = no
        user = root
        server = /root/bin/example.py #指定服务器程序位置
        server_args = /root/bin/example.py
    }
     

    2. 使用标准输入输出搭建 TCP 服务器

    编写 exmaple.py 服务器端程序,主要要求如下:
    1、服务器采用 xinetd 的方式运行
    2、服务器监听在 0.0.0.0 的 51423 端口上
    3、收到客户端数据后,将其加上时间戳后回送给客户端
    4、如果客户端发过来的字符全是空白字符,则终止与客户端的连接
    5、采用标准输入输出的方式进行编写

    方案
    当使用 xinetd 的时候,它通过两个方法传递 socket:如文件描述符 0 1。相应的,调用 sys.stdin.readline()接收数据。
    因为标准输出 sys.stdout 默认是被缓冲的,不会及时把信息显示在屏幕上,所以为了实时性,需要调用 sys.stdou.flush()

    实现此案例需要按照如下步骤进行。
    步骤一:编写脚本

     
    [root@py01 bin]# vim example.py
    #!/usr/bin/env python
    #coding:utf-8
    
    import sys
    import time
    
    sys.stdout.write('Please enter a string:
    > ')
    sys.stdout.flush()
    
    while True:
        line = sys.stdin.readline().strip()
        if not line:
            break
        sys.stdout.write('[%s] %s
    > ' % (time.ctime(), line))
        sys.stdout.flush()
     

    步骤二:验证执行效果

     
    [root@py01 bin]# telnet 127.0.0.1 51423
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Please enter a string:
    > hello world!
    [Mon Jul 6 18:49:54 2015] hello world!
    > #此处直接回车,退出程序
    Connection closed by foreign host.
    [root@py01 bin]#
     

    3. 使用 socket 对象搭建 TCP 服务器
    编写 exmaple.py 服务器端程序,主要要求如下:
    1、服务器采用 xinetd 的方式运行

    2、服务器监听在 0.0.0.0 的 51423 端口上

    3、收到客户端数据后,将其加上时间戳后回送给客户端

    4、如果客户端发过来的字符全是空白字符,则终止与客户端的连接

    5、采用 socket 对象的方式进行编写

    方案
    使用 socket“更像”网络服务器程序。因为客户端的请求首先要发送到超级守护进程xinetd,所以需要根据 xinetd 传递过来的文件描述符建立 socket 对象。

    通过调用socket.fromfd()可以建立 socket 对象

    实现此案例需要按照如下步骤进行。
    步骤一:编写脚本

     
    [root@py01 bin]# mv example.py example1.py #将实验 2 的服务器程序改名
    root@py01 bin]# vim example.py #建立新的服务器程序

    #!/usr/bin/env python
    #coding:utf-8

    import sys
    import time
    import socket

    s = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
    s.sendall('Welcome! > ')

    while True:
        data = s.recv(4096).strip()
        if not data:
            break
        s.sendall('[%s] %s > ' % (time.ctime(), data))
    s.close()


     

    步骤二:验证执行结果

     
    [root@py01 bin]# telnet 127.0.0.1 51423
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Welcome!
    > hello world!
    [Mon Jul 6 19:03:02 2015] hello world!
    > #此处直接输入回车,退出连接
    Connection closed by foreign host.
     

    例子:

    step1:

    yum -y install xinetd
    yum -y install tftp-server

    step2:

     
    [root@host-192-168-3-6 day10]# vim /etc/xinetd.d/pyserv 
    service pyserv
    {
        flags       = NAMEINARGS
        type        = UNLISTED
        port        = 12345
        socket_type = stream
        protocol    = TCP
        wait        = no
        user        = root
        server      = /root/day10/example.py
        server_args = /root/day10/example.py
    }
     

    step3:

     
    /root/day10/example.py内容:
    #!/usr/bin/env python
    #coding:utf8
    
    import sys 
    
    print "Welcome ."
    print "Enter Line."
    
    sys.stdout.flush()
    line = sys.stdin.readline().strip()
    sys.stdout.write("You entered %s chars" % len(line))
     

    测试:

     
    [root@host-192-168-3-6 ~]# chmod +x /root/day10/example.py
    
    root@host-192-168-3-6 ~]# cd /root/day10/
    [root@host-192-168-3-6 day10]# python example.py 
    Welcome .
    Enter Line.
    hello world!
    You entered 12 chars
    [root@host-192-168-3-6 day10]# 
    
    [root@host-192-168-3-6 day10]# systemctl restart xinetd 
    [root@host-192-168-3-6 day10]# netstat -tulnp| grep 12345
    tcp6       0      0 :::12345                :::*                    LISTEN      3738/xinetd         
    [root@host-192-168-3-6 day10]# 
    
    [root@host-192-168-3-6 day10]# telnet 127.0.0.1 12345
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Welcome.
    Enter Line.
    agfasfasdfa
    You entered 11 chars
    Connection closed by foreign host.
    [root@host-192-168-3-6 day10]# 
     

    修改/root/day10/example.py内容

     
    #!/usr/bin/env python
    #coding:utf8
    
    import sys 
    import time
    
    
    sys.stdout.write('>')
    sys.stdout.flush()
    
    
    while True:
        data = sys.stdin.readline()
        if not data.strip():
            break
        sys.stdout.write("[%s] %s>" %(time.ctime(),data))
        sys.stdout.flush()
        
     

    测试:

    [root@host-192-168-3-6 day10]# ./example.py 
    >hello world
    [Mon Jun 19 10:19:20 2017] hello world
    >

    修改/root/day10/example.py内容:

     
    #!/usr/bin/env python
    #coding:utf8
    
    import sys 
    import time
    import socket
    
    s = socket.fromfd(sys.stdin.fileno(),socket.AF_INET,socket.SOCK_STREAM)
    s.sendall("Welcome!
    ")
    s.send("you are connected from %s
    " % str(s.getpeername()))
    s.send("Now: %s
    " % time.ctime())
     

    测试:

     
    [root@host-192-168-3-6 day10]# telnet 127.0.0.1 12345
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Welcome!
    you are connected from ('127.0.0.1', 51738)
    Now: Mon Jun 19 10:51:18 2017
    Connection closed by foreign host.
     

    修改/root/day10/example.py内容:

     
    #!/usr/bin/env python
    #coding:utf8
    
    import sys 
    import time
    import socket
    
    s = socket.fromfd(sys.stdin.fileno(),socket.AF_INET,socket.SOCK_STREAM)
    
    while True:
        data = s.recv(4096)
        if not data.strip():
            break
        s.send("[%s] %s " % (time.ctime(),data))
    
    s.close()
     

    测试:

     
    [root@host-192-168-3-6 day10]# telnet 127.0.0.1 12345
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    hello
    [Mon Jun 19 10:54:12 2017] hello
     world
    [Mon Jun 19 10:54:16 2017] world
     
     
  • 相关阅读:
    解决The markup in the document following the root element must be well-formed.
    全排列算法:递归和非递归实现
    利用异或运算实现交换2个数据
    dojo 代码调试
    dogo 官方翻译 Ajax with dojo/request
    dojo 官方翻译 dojo/Deferred
    dojo 官方翻译 dojo/aspect
    get app id
    [转]解决eclipse无法设置NDK问题
    关于二级指针
  • 原文地址:https://www.cnblogs.com/zhongguiyao/p/11049445.html
Copyright © 2011-2022 走看看