python服务器的搭建

早先对于python服务器的理解不够充分

对于这门语言的理解一直只处于前端网页的制作与后端数据处理方面

因此对于python服务器的搭建几乎处于空白阶段

对此我表示需要深刻的恶补

因此从头学习python服务器的搭建

结果没想到python服务器处理tcp请求也是使用socket的方式

因此对于我的学习来说还算是比较顺利

 1 p_port = ('192.168.7.11', 9999)
 2 web = socket.socket()
 3 web.bind(ip_port)
 4 web.listen(5)
 5 
 6 while True:
 7     print 'I am waiting for the client'
 8     conn, addr = web.accept()
 9     # thread = threading.Thread(target=jonnys, args=(conn, addr))
10 
11     data = conn.recv(1024)
12     print data
13     conn.sendall(str('<h1>welcome nginx</h1>'))
14     conn.close()

以上是简单的服务器

附使用简单客户端

import socket

ip_port = ('192.168.7.11', 9999)
sk = socket.socket()
sk.connect(ip_port)
sk.sendall('haha douyu\n')
sk.sendall('you like join this\n')
server_reply = sk.recv(1024)
# server_reply_three = sk.recv(1024)
print server_reply
# print server_reply_three
# sk.sendall('join this\n')
# server_reply_two = sk.recv(1024)
# print server_reply_two
sk.close()

使用ThreadingTCPServer, StreamRequestHandler来实现多线程服务器处理

但是有一个小BUG需要解决

from SocketServer import ThreadingTCPServer, StreamRequestHandler
import traceback

class MyStreamRequestHandlerr(StreamRequestHandler):
    """
    #StreamRequestHandler,并重写handle方法
    #(StreamRequestHandler继承自BaseRequestHandler)
    """
    def handle(self):
        while True:
            #客户端主动断开连接时,self.rfile.readline()会抛出异常
            try:
                #self.rfile类型是socket._fileobject,读写模式是"rb",方法有
                #read,readline,readlines,write(data),writelines(list),close,flush
                data = self.rfile.readline().strip()
                # if data == '\'\'':

                # print data
                print "receive from (%r):%r" % (self.client_address, data)
                # data = self.request.recev(1024).strip

                #self.client_address是客户端的连接(host, port)的元组)

                #self.wfile类型是socket._fileobject,读写模式是"wb"
                self.wfile.write(data.upper())
            except:
                traceback.print_exc()
                break

if __name__ == "__main__":
    #telnet 127.0.0.1 9999
    host = ""       #主机名,可以是ip,像localhost的主机名,或""
    port = 9999     #端口
    addr = (host, port)

    #ThreadingTCPServer从ThreadingMixIn和TCPServer继承
    #class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
    server = ThreadingTCPServer(addr, MyStreamRequestHandlerr)

    #启动服务监听
    server.serve_forever()

当客户端主动关闭套接字时

服务器会出现死循环产生子线程来读取空的信息

从而使服务器崩溃

因此诞生第三个版本

# -*- coding: UTF-8 -*-
import socket
import threading, getopt, sys, string

opts, args = getopt.getopt(sys.argv[1:], "hp:l:", ["help", "port=", "list="])
#设置默认的最大连接数和端口号,在没有使用命令传入参数的时候将使用默认的值
list=50
port=9999
def usage():
    print """
    -h --help             print the help
    -l --list             Maximum number of connections
    -p --port             To monitor the port number
    """
for op, value in opts:
    if op in ("-l","--list"):
        list = string.atol(value)
    elif op in ("-p","--port"):
        port = string.atol(value)
    elif op in ("-h"):
        usage()
        sys.exit()

def jonnyS(client, address):
    try:
    #设置超时时间
        client.settimeout(500)
    #接收数据的大小
        buf = client.recv(2048)
        print buf
    #将接收到的信息原样的返回到客户端中
        client.send(buf)
    #超时后显示退出
    except socket.timeout:
        print 'time out'
    #关闭与客户端的连接
    client.close()

def main():
    #创建socket对象。调用socket构造函数
    #AF_INET为ip地址族,SOCK_STREAM为流套接字
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #将socket绑定到指定地址,第一个参数为ip地址,第二个参数为端口号
    sock.bind(('192.168.7.11', port))
    #设置最多连接数量
    sock.listen(list)
    while True:
    #服务器套接字通过socket的accept方法等待客户请求一个连接
        client, address = sock.accept()
        thread = threading.Thread(target=jonnyS, args=(client, address))
        thread.start()

if __name__ == '__main__':
    main()
最终版服务器

这个版本当服务器与客户端完成通信之后会由服务器关闭套接字

还包括延时功能

因此不会有第二个程序的bug

posted @ 2017-04-20 14:56  xiaoYYProcess  阅读(23243)  评论(2编辑  收藏  举报