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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM