python核心编程学习笔记-2016-08-23-01-习题16-13

        习题16-13

        名字服务器。设计并实现一个名字服务器。这个服务器负责维护一个主机名-端口对的数据库,以及一个描述这个服务器提供的服务的字符串。 选择一个或几个服务器到你的名字服务器上进程“注册”。(注意,这时,这些服务器是名字服务器的客户)。每一个客户在启动的时候,都不知道它们想要找的服务器的信息。名字服务器的客户也是这样。这些客户应该发送一个请求到名字服务器,说明它们想要得到什么服务。名字服务器返回一个主机名-端口对给客户,客户这时就可以连到合适的服务器来处理它的请求。

        本人想法是这样,这里需要至少三个脚本,一个名字服务器脚本,一个普通服务器脚本,一个客户端脚本。本人理解是,客户端先同名字服务器连接,向名字服务器发送描述服务内容的字符串,而名字服务器根据字符串内容,向客户端返回包含一个普通服务器主机名和端口的字符串,客户端再连接到相应的普通服务器上,来让该普通服务器处理客户端的请求。

        题目中说,服务器负责维护一个主机名-端口对的数据库,以及一个描述这个服务器提供的服务的字符串。由于本人还不会数据库的相关知识,这里打算用字典形式,即键是描述该服务器内容的字符串(在脚本中是'ctime'),值是一个包含主机名和端口的元组。

        代码如下:

        名字服务器脚本

#-*-coding: utf-8-*-

from socket import *

servs = {'ctime': ('localhost', 50007)} # 这里只以连接一个普通服务器为例子

HOST = ''
PORT = 21567
ADDR = (HOST, PORT)

nameServ = socket(AF_INET, SOCK_STREAM)
nameServ.bind(ADDR)
nameServ.listen(5)

while True:
    print "nameServ waiting for connection..."
    conn, addr = nameServ.accept()
    print "Connected by", addr
    while True:
        data = conn.recv(1024)
        if not data:
            break
        elif data in servs.iterkeys():
            respond = str(servs[data]) # 把主机名和端口发送给客户端
        else:
            respond = "You request is beyond our ability."
        conn.sendall(respond)
    conn.close()
nameServ.close()
          普通服务器脚本

#-*-coding: utf-8-*-

from socket import *
from time import ctime

HOST = 'localhost' 
PORT = 50007 
BUFSIZ = 1024 
ADDR = (HOST, PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 

while True:
    print "waiting for connection..." 
    tcpCliSock, addr = tcpSerSock.accept() 
    print "...connected from:", addr
    
    while True: 
        data = tcpCliSock.recv(BUFSIZ) 
        if not data: 
            break
        tcpCliSock.send('[%s] %s' % (ctime(), data)) 

    tcpCliSock.close() 
tcpSerSock.close()    
         客户端脚本

#-*-coding: utf-8-*-

from socket import *
import re

nameServHost = 'localhost'
nameServPort = 21567
ADDR = (nameServHost, nameServPort)

clnt = socket(AF_INET, SOCK_STREAM) 
clnt.connect(ADDR) # 先与名字服务器连接

while True:
    smsg = raw_input("What can I server you? ")
    if not smsg: break
    clnt.sendall(smsg)
    rmsg = clnt.recv(1024) 
    if rmsg:
        servHost = re.search('[a-z]+', rmsg).group() # 使用正则表达式获取主机名和端口
        servPort = int(re.search('\d+', rmsg).group())
        break
    else:
        print "Something wrong occurs."
        break
clnt.close()

servclnt = socket(AF_INET, SOCK_STREAM)
servclnt.connect((servHost, servPort)) # 连接到主机名和端口所指向的普通服务器

while True:
    sdata = raw_input("Enter anything: ")
    if not sdata: break
    servclnt.sendall(sdata)
    rdata = servclnt.recv(1024)
    if not rdata:
        break
    print rdata
servclnt.close()   
          附加题(1)和(3)看不懂,(2)就是使用文件把连接信息记录下来就可以了。

          本人尚处计算机小白阶段,如果有任何理解有误,恳请指正!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值