python编写借助linux中的xinetd守护进程实现我们的网络程序(select、重定向标准输入输出)


典型的unix存在许多服务器。4.3 BSD面世之前,所有的这些服务都有进程与之关联。这些程序遵循unix系统服务的启动流程。而且每个服务执行几乎相同的启动任务:

   (1 )创建套接字,将端口绑定在套接字上

     ( 2 ) 等待一个连接(tcp)或者一个数据报(udp),然后派生子进程

     ( 3 ) 子进程为客户端服务,父进程继续等待下一个连接


这个模型存在两个问题:

   ( 1 ) 所有的守护进程含有相同的启动代码,既表现在创建套接字上,也表现在演变成守护进程上

   ( 2 ) 每个进程都在进程表中占有一项


xinted的出现简化了这些:

   

这幅图出现在<unix网络编程卷一>中

inetd的工作原理

inetd守护进程的工作流程:

1. 在启动阶段,读入配置文件(/etc/inetd.conf  /etc/xinetd.conf),对于配置文件中的每个服务创建一个适当类型(TCP或UDP)的套接口。新创建的每个套接口都被加入到将由某个select调用使用的一个描述字集中。

2. 为每个套接口调用bind(根据/etc/services中的配置项)。

3. 对于每个TCP套接口,调用listen以接受外来的连接请求;

4. 创建完毕所有套接口后,调用select等待其中任何一个套接口变为可读。inetd的大部分时间阻塞于select调用内部,等待某个套接口变为可读。

5. 当select返回指出某个套接口可读以后,如果该套接口是TCP套接口,而且其服务器为nowait类型,则调用accept接受这个连接。

6. inetd调用fork派生进程,并由子进程处理服务请求。

      l  子进程关闭要处理的套接口描述字之外的所有描述字(对于TCP为accept返回的套接口,对于UDP为最初创建的套接口),子进程三次调用dup2,把待处理套接口的描述字复制到描述字0、1、2上;然后关闭原套接口描述字。因此,子进程打开的描述字只有0、1、2。子进程从标准输入读,相当于从所处理的套接口读;子进程往标准输出或标准错误上写,相当于往所处理套接口写。

     l  子进程根据login-name(user)的配置值,如果不是root,子进程则调用setgid和setuid把自身改为指定的用户。

     l  子进程调用exec执行由配置文件指定的程序( 如上例中的/root/echo)来具体处理请求。

7. 如果5中返回的是TCP套接口,则父进程先关闭接受请求产生的连接套接口。父进程在此调用select,等待下一个变为可读的套接口。

 



现在我们基于以上叙述写一个使用xinetd的echo服务器:

#! /usr/bin/python
import socket, sys, time
sys.stdout.write("Welcome to my server....\n")
sys.stdout.flush()
time = time.ctime()
sys.stdout.write("Server time is : "+str(time)+'\n')
sys.stdout.flush()
sys.stdout.write("Please input a string: ")
sys.stdout.flush()


data = sys.stdin.readline()

sys.stdout.write("OK, you enter: " + data )
sys.stdout.flush()



#! /usr/bin/python
import socket, time, sys

conn_read = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
conn_write = socket.fromfd(sys.stdout.fileno(), socket.AF_INET, socket.SOCK_STREAM)

conn_write.sendall("Welcome to my server....\n")
conn_write.sendall("Server time is : "+str(time.ctime()))
conn_write.sendall("Please input a string: ")

data = conn_read.recv(512)

conn_write.sendall("OK, you enter: " + data)

conn_write.close()
conn_read.close()


上述两个程序都可以实现功能,UDP的话暂时出现问题,稍后跟新
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值