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:\n> ')
sys.stdout.flush()

while True:
    line = sys.stdin.readline().strip()
    if not line:
        break
    sys.stdout.write('[%s] %s\n> ' % (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!\n> ')

while True:
    data = s.recv(4096).strip()
    if not data:
        break
    s.sendall('[%s] %s\n> ' % (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!\n")
s.send("you are connected from %s\n" % str(s.getpeername()))
s.send("Now: %s\n" % 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
 
 

 

posted @ 2019-06-19 09:20  钟桂耀  阅读(450)  评论(0编辑  收藏  举报