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的話暫時出現問題,稍後跟新
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章