ホームページ >バックエンド開発 >Python チュートリアル >Python は単純な HttpServer サーバーを実装します

Python は単純な HttpServer サーバーを実装します

巴扎黑
巴扎黑オリジナル
2017-09-26 10:35:073177ブラウズ

この記事では、主に Python で実装された単純な HttpServer サーバーのサンプルを紹介します。編集者が非常に優れていると考えたので、参考として共有します。エディターに従って見てみましょう

Tomcat に似た単純なサーバーを作成するには、まず次の点を理解する必要があります:

1. クライアントとサーバーの役割と機能

ロール A はロールからデータを要求します。 B. このとき、Aはクライアント、Bはサーバーとみなすことができます。クライアントの主な役割は、リクエストを送信し、送信したリクエストに基づいてサーバーから返されるリクエスト情報を受信することです。一方、サーバーの主な役割は、リクエストを受信して​​リクエスト データを返すことです。

2. ブラウザとは何か、そしてその仕組み

私たちはよく B/S、C/S アーキテクチャと言いますが、いわゆる B/S はブラウザ/サーバーを指し、C/S はクライアント/サーバーを指します。実際にはB/Sアーキテクチャ ブラウザ上に表示されるのはC/Sアーキテクチャではなく、最終的にブラウザ上に表示されるものがB/Sアーキテクチャである限り、ブラウザに適用されるプログラムです。一般的なリーグ・オブ・レジェンドのゲーム。ただし、ブラウザは特別なクライアントであるため、本質的には C/S アーキテクチャのみです。

ブラウザの特別な点は、次の 3 つのエンジンがあることです:

  • DOM 解析エンジン: つまり、ブラウザは HTML を解析できます

  • スタイル解析エンジン: つまり、ブラウザは解析できますCSS

  • スクリプト解析エンジン: つまり、ブラウザはJAVASCRIPT

を解析できます。 3. ソケット

前述のクライアントとサーバー、それらの間の接続とデータ転送を実現する方法、これがソケットです。プログラミング言語 Socket プログラミングがあり、Socket の機能はネットワーク通信の機能を提供することです

4. HTTP プロトコルと HTTP と TCP/TP の違い

クライアントとサーバーは、ネットワーク通信の機能を実現します。ソケットを介してデータ転送を実現できます。このプロトコルはデータ送信を規制します。つまり、クライアントとサーバー間で送信されるデータは、特定の仕様と標準に従って送信される必要があり、やみくもに送信することはできません。

TCP/IP (伝送制御プロトコル/インターネット プロトコル): 伝送制御プロトコル/インターネット プロトコル

HTTP (ハイパーテキスト転送プロトコル): ハイパーテキスト転送プロトコル。

TCP/TP の違い:

わかりやすく例えると、TCP/TP は道路であり、HTTP は道路上の車であるため、HTTP は TCP/TP に基づいている必要があります。

HTTP は主に Web プログラムで使用され、元々は HTML ページを発行および受信するためのメソッドを提供するために設計されました。これは非常に抽象的で理解しにくいかもしれません。具体的には、Web サイトにアクセスしたときに、その Web サイトに基づくコンテンツ (html、css、JavaScript など) を取得するだけで済みます。しかし、ブラウザーが受信したリソース パッケージを取得したところ (Fiddler ツールを使用できます)、Web ページに必要なエンティティ コンテンツに加えて、次の情報も含まれていることがわかりました:

HTTP/1.1 200 OK
キャッシュ-コントロール: プライベート
コンテンツ タイプ: text /plain; charset=utf-8
コンテンツ エンコーディング: gzip
変更: Accept-Encoding
サーバー: Microsoft-IIS/7.5
X-AspNet バージョン: 4.0.30319
X -Powered-By: ASP.NET
Date : Tue, 24 Jan 2017 03:25:23 GMT
Connection: close
Content-Length: 661

これは、たとえば、Content-Type は http プロトコル仕様を指します。 Content-Encoding は送信時のファイルの形式を指定します。上記以外にもたくさんありますが、ここではこれらのパラメータの意味を一つ一つ紹介しません

5. URLの意味

URL (Uniform Resource Locator) をそのままURLと呼びます。 URL を解析します。説明してください: http://198.2.17.25:8080/webapp/index.html

これは、IP 198.2.17.25 のサーバーのディレクトリの下で webapp のindex.html を見つけることを意味します

しかし、それは何ですか?よく見かけるのは次のような URL です: http://goodcandle.cnblogs.com/archive/2005/12/10/294652.aspx

実際、これは上記と同じですが、ドメイン名解決があります。ここでは、goodcandle.cnblogs.com を対応する IP アドレスに解決できます

上記の 5 つの点を理解したら、コードを書き始めます

webServer.py


import socket
import sys
import getFileContent
#声明一个将要绑定的IP和端口,这里是用本地地址
server_address = ('localhost', 8080)
class WebServer():
  def run(self):
    print >>sys.stderr, 'starting up on %s port %s' % server_address
    #实例化一个Socket
    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #绑定IP和端口
    sock.bind(server_address)
    #设置监听
    sock.listen(1)
    #这里首先给个死循环,其实这里是需要多线程的,再后续版本将会实现
    while True:
      #接受客户端的请求并得到请求信息和请求的端口信息
      connection, client_address = sock.accept()
      print >>sys.stderr, 'waiting for a connection'
      try:
        #获取请求信息
        data = connection.recv(1024)
        if data:
          #发送请求信息
          connection.sendall(getFileContent.getHtmlFile(data))
      finally:
        connection.close()

if __name__ == '__main__':
  server=WebServer()
  server.run()

webServer.py は非常に明確で簡潔です。connection.sendall()サーバーはブラウザに情報を返しますが、送信されるデータは HTTP プロトコル仕様に従う必要があります
getFileContent.py は、送信されたデータの HTTP プロトコル仕様を処理します


import sys
import os

#得到要发送的数据信息
def getHtmlFile(data):
  msgSendtoClient=""
  requestType=data[0:data.find("/")].rstrip()
  #判断是GET请求还是POST请求
  if requestType=="GET":
    msgSendtoClient=responseGetRequest(data,msgSendtoClient)
  if requestType=="POST":
    msgSendtoClient=responsePostRequest(data,msgSendtoClient)
  return msgSendtoClient

#打开文件,这里不直接写,二是去取要发送的文件再写
def getFile(msgSendtoClient,file):
    for line in file:
     msgSendtoClient+=line
    return msgSendtoClient

#筛选出请求的一个方法
def getMidStr(data,startStr,endStr):
  startIndex = data.index(startStr)
  if startIndex>=0:
    startIndex += len(startStr)
    endIndex = data.index(endStr)
    return data[startIndex:endIndex]

#获取要发送数据的大小,根据HTTP协议规范,要提前指定发送的实体内容的大小
def getFileSize(fileobject):
  fileobject.seek(0,2)
  size = fileobject.tell()
  return size

#设置编码格式和文件类型
def setParaAndContext(msgSendtoClient,type,file,openFileType):
  msgSendtoClient+="Content-Type: "+type+";charset=utf-8"
  msgSendtoClient+="Content-Length: "+str(getFileSize(open(file,"r")))+"\n"+"\n"
  htmlFile=open(file,openFileType)
  msgSendtoClient=getFile(msgSendtoClient,htmlFile)
  return msgSendtoClient

#GET请求的返回数据
def responseGetRequest(data,msgSendtoClient):
  return responseRequest(getMidStr(data,'GET /','HTTP/1.1'),msgSendtoClient)

#POST请求的返回数据
def responsePostRequest(data,msgSendtoClient):
  return responseRequest(getMidStr(data,'POST /','HTTP/1.1'),msgSendtoClient)

#请求返回数据
def responseRequest(getRequestPath,msgSendtoClient):
  headFile=open("head.txt","r")
  msgSendtoClient=getFile(msgSendtoClient,headFile)
  if getRequestPath==" ":
    msgSendtoClient=setParaAndContext(msgSendtoClient,"text/html","index.html","r")
  else:
    rootPath=getRequestPath
    if os.path.exists(rootPath) and os.path.isfile(rootPath):
      if ".html" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"text/html",rootPath,"r")
      if ".css" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"text/css",rootPath,"r")
      if ".js" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"application/x-javascript",rootPath,"r")
      if ".gif" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"image/gif",rootPath,"rb")
      if ".doc" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"application/msword",rootPath,"rb")
      if ".mp4" in rootPath:
        msgSendtoClient=setParaAndContext(msgSendtoClient,"video/mpeg4",rootPath,"rb")
    else:
      msgSendtoClient=setParaAndContext(msgSendtoClient,"application/x-javascript","file.js","r")
  return msgSendtoClient

以上がPython は単純な HttpServer サーバーを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。