Python Http 多客户端和服务器(串行)-- 从配置文件获取

1.源代码

#!/usr/bin/env python
# coding=utf8
# si.hairui, 2016.11.24
# Http Client, Python 2.7.5
# ---------------------------------------------
# 1.上电之后读取配置文件,获取客户端列表和服务器列表;
# 2.校验配置文件中客户端IP的真实性(有效性);
# 3.解析服务端URL字段内容
# 4.注册线程,开始并发请求
# ---------------------------------------------

# ---------------------------------------------
#    模块导入
# ---------------------------------------------
import socket
import httplib

# ---------------------------------------------
#    全局变量
# ---------------------------------------------
# 打印开关
PRINT_SW = 0  # 0-关,1-开

# 客户端信息列表
HTTP_CLIENT_LIST = []
'''
HTTP_CLIENT_LIST = [

    {'ip': '192.168.0.218', 'portbegin': 464,   'portend': 464},
    {'ip': '192.168.0.220', 'portbegin': 34684, 'portend': 34685}
]
'''
# 服务器信息
HTTP_SERVER_LIST = []
'''
HTTP_SERVER_LIST = [

    'http://192.168.0.236/web/page/',
    'http://192.168.0.235:80/web/video/aboutHFS/HFS.txt'
]
'''

# ---------------------------------------------
#    函数实现
# ---------------------------------------------
# 读取配置文件,返回配置文件字符串
'''
{
    'clients': [{'ip': '192.168.0.218', 'portbegin': 464, 'portend': 464}, {'ip': '192.168.0.220', 'portbegin': 34684, 'portend': 34685}],
    'servers': ['http://192.168.0.236/web/page/', 'http://192.168.0.235:80/web/video/aboutHFS/HFS.txt', 'http://192.168.0.235']
}
'''
def readCfgFile():
    try:
        with open('config.cfg', 'r') as f:
            return f.read()  # 返回字符串

    except:
        print "Error: ReadCfgFile fail!"
        return None


# 获取本地业务地址,放入序列svrIps
def getServiceIp(svrIps):
    hostname = socket.gethostname()
    localIP = socket.gethostbyname(socket.gethostname())
    if PRINT_SW:
        print "Hostname:"
        print "    %s" % hostname
        print "Local IP:"
        print "    %s" % localIP

    ipList = socket.gethostbyname_ex(socket.gethostname())
    if PRINT_SW:
        print ipList
    for ips in ipList:
        # 过滤空序列、主机名
        if ips and (not isinstance(ips, str)):  # ips是一个序列,其中每个元素是IP地址字符串
            '''
            if PRINT_SW:
                print "External IP:"
            '''
            for ip in ips:
                '''
                if PRINT_SW:
                print "    %s" % ip
                '''
                svrIps.append(ip)


# 获取客户端列表,eg: HTTP_SERVER_LIST = list(getClientInfo())
def getClientInfo():
    cfginfo = eval(readCfgFile())
    # 校验配置文件中的IP
    # a.首先获取本地业务IP地址
    locIps = []
    getServiceIp(locIps)
    # b.然后对比配置文件中的地址
    validDicts = []  # 保存配置文件中的合法元素
    for sockdict in cfginfo['clients']:
        try:
            locIps.index(sockdict['ip'])
        except ValueError :  # 如果发生异常,说明sockdict中的IP地址不在本PC上,则丢掉
            print "Error: " + sockdict['ip'] + " in <config.cfg> is not valid, it will be discarded!!!"
            continue
        else:  # 没有异常,则保存该字典
            validDicts.append(sockdict)
    if PRINT_SW:
        print validDicts
    return validDicts


# 获取服务端列表,eg: HTTP_SERVER_LIST = list(getServerInfo())
def getServerInfo():
    cfginfo = eval(readCfgFile())
    if PRINT_SW:
        print cfginfo['servers']
    return cfginfo['servers']


# 根据URL获取Server的IP、port、filepath,以字典的形式返回
def getServerSocket(url):
    strIp = ""
    port = 0
    filepath = ""
    if 0 != url.find("http://"):  # URL必须以“http://”开头(暂时不考虑https的场景)
        print "Error: URL is invalid: %s !!!" % url
        return
    # 首先,去掉“http://”
    urlUnhttp = url[7:]
    # 然后判断有无“/”
    firstXieGnagLoc = urlUnhttp.find("/")  # urlUnhttp中第一个“/”下标
    firstMaoHaoLoc = urlUnhttp.find(":")  # urlUnhttp中第一个“:”下标
    if (-1) == firstXieGnagLoc and (-1) == firstMaoHaoLoc:  # "192.168.0.235"
        strIp = urlUnhttp
        port = 80
        filepath = "/"
    elif (-1) == firstXieGnagLoc and firstMaoHaoLoc > 0: # "192.168.0.235:8988"
        strIp = urlUnhttp[:firstMaoHaoLoc]
        port = int(urlUnhttp[firstMaoHaoLoc + 1:])
        filepath = "/"
    elif firstXieGnagLoc > 0 and (-1) == firstMaoHaoLoc: # "192.168.0.235/..."
        strIp = urlUnhttp[:firstXieGnagLoc]
        port = 80
        filepath = urlUnhttp[firstXieGnagLoc:]
    elif firstXieGnagLoc > 0 and firstMaoHaoLoc > 0:  # "192.168.0.235:8988/..."
        strIp = urlUnhttp[:firstMaoHaoLoc]  # 这种情况下,默认URL中“:”在“/”左边
        port = int(urlUnhttp[firstMaoHaoLoc + 1:firstXieGnagLoc])
        filepath = urlUnhttp[firstXieGnagLoc:]
    else:
        print "Error: URL is unable reslute: %s!!!" % url

    svrdict = {}.fromkeys(["ip", "port", "filepath"])
    svrdict["ip"] = strIp
    svrdict["port"] = port
    svrdict["filepath"] = filepath

    return svrdict


# 轮询服务器和客户端发起HTTP请求,eg: runHttpCliet(HTTP_CLIENT_LIST, HTTP_SERVER_LIST)
def runHttpCliet(clients=[], servers=[]):
    if (None == clients) or (None == servers):  # 保护一下
        print "Error: clients or servers is None!!!"
        return
    for urlstr in servers:
        svrdict = getServerSocket(urlstr)  # 解析URL
        print "svrdict =", svrdict
        if None == svrdict["ip"] or None == svrdict["port"]:
            print "Error: Server is invalid!!!", svrdict
            continue  # 执行下一个server
        for httpClient in clients:
            print "httpClient =", httpClient
            for clientPort in range(httpClient['portbegin'], httpClient['portend'] + 1):
                try:
                    myHttpConn = httplib.HTTPConnection(svrdict["ip"], svrdict["port"],
                                                        timeout = 2, # 设置连接超时等待(单位:s)
                                                        source_address = (httpClient["ip"], clientPort))
                    myHttpConn.debuglevel = 0  # 调试模式开关
                    if 0 == myHttpConn.debuglevel:
                        print "    ---- Http Request ----"
                        print "    " + httpClient["ip"] + ":", clientPort, \
                            " --> " + svrdict["ip"], svrdict["port"], ": " + svrdict['filepath']

                    myHttpConn.request("GET", svrdict['filepath'])  # 资源路径以“/”开始

                    myHttpResp = myHttpConn.getresponse()
                    if 0 == myHttpConn.debuglevel:
                        print "   ", myHttpResp.status, myHttpResp.reason  # 响应码和状态信息
                        # 此处必须读响应内容,如果不读取,buff将溢出!!!
                        data1 = myHttpResp.read()
                        pass
                except:
                    print "Exception!"
                    continue
                finally:
                    # print data1   # 打印响应内容
                    print "    Http(%s:%s --> %s:%s) will be closed!" % \
                          (httpClient["ip"], str(clientPort), svrdict["ip"], str(svrdict["port"]))
                    myHttpConn.close()  # 关闭连接


# ---------------------------------------------
#    main模块
# ---------------------------------------------
if __name__ == "__main__":
    HTTP_CLIENT_LIST = list(getClientInfo())  # 构造客户端
    print "HTTP_CLIENT_LIST =", HTTP_CLIENT_LIST
    HTTP_SERVER_LIST = getServerInfo()  # 构造服务端
    print "HTTP_SERVER_LIST =", HTTP_SERVER_LIST
    runHttpCliet(HTTP_CLIENT_LIST, HTTP_SERVER_LIST)  # 发起请求




2.配置文件

# config.cfg
# clients: {"ip": "客户端的IP地址", "portbegin": 起始端口号, "portend": 结尾端口号}
# servers: 暂时只支持 “http://IP地址”的格式的URL 


{
    "clients" : [
	#{ "ip": "192.168.0.221", "portbegin": 1, "portend": 65535 },
	{ "ip": "192.168.0.220", "portbegin": 65333, "portend": 65433 },
    ],

    "servers" : [
        "http://192.168.0.235/web/video/aboutHFS/HFS.txt"
    ]
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值