ソケットとは
コンピューターは、その名前が示すように、計算に使用されます。そのため、計算が必要な条件を入力し、計算結果を出力する入出力も必要となります。これらの入出力はI/O(入出力)として抽象化できます。
Unix コンピューターは、ファイルの抽象化を通じて IO を処理します。入出力、つまり異なるコンピュータープロセス間の通信もあります。したがって、この通信もファイルの抽象ファイル記述子を通じて実行されます。
同じコンピューター上で、プロセスはこのように通信できます。異なるコンピューターの場合はどうなるでしょうか?ネットワーク上のさまざまなコンピュータも通信できるため、ネットワーク ソケットを使用する必要があります。ソケットは、異なるコンピューター間の通信を抽象化したものです。彼は、TCP/IP プロトコルのアプリケーション層とトランスポート層の間の抽象化に取り組んでいます。以下に示すように:
サーバー通信
ソケットは、異なるコンピュータ間の通信、つまりネットワーク通信を保証します。 Web サイトの場合、通信モデルはクライアント/サーバー通信です。両端はソケット オブジェクトを確立し、ソケット オブジェクトを通じてデータを送信します。通常、サーバーはワイヤレス ループ内でクライアントの接続を待機しています。
ソケット通信例
ソケットインターフェースはオペレーティングシステムによって提供され、オペレーティングシステムを呼び出すためのインターフェースです。もちろん、高級言語は通常、便利な関数インターフェイスをカプセル化します。これは、Python コードを使用した単純なソケット サーバーの例です。
リーリー
リーリー
TCP スリーウェイ ハンドシェイク
Python コードでソケットを記述するのは簡単です。伝説の TCP スリーウェイ ハンドシェイクはどのように具体化されるのでしょうか?スリーウェイハンドシェイクとは何ですか?
3 番目のステップ: サーバーから応答を受信した後、クライアントは接続を確立するためにサーバーに確認を送信します。
次の比喩を使用してください
C: 予約を取りますか?
S:
についてC: わかりました
デート
これにより、TCP 接続セッションが確立されます。切断したい場合の一般的なプロセスは次のとおりです:
上の写真は、スリーウェイ ハンドシェイク ソケットの具体的なプロセスも明確に示しています。
connect を呼び出した後、クライアント ソケット オブジェクトはブロックされます。このプロセスは syn を送信します。
単純な HTTP サービスを構築するには、HTTPServer を継承する必要があり、リクエストハンドラーも BaseHTTPRequestHandler を継承する必要があります。 Python は SimpleHTTPServer という例を実装しています。したがって、SimpleHTTPServer を分析して、以前のクラスのいくつかを使用して http サービスを構築する方法を確認します。
Python のシンプルさと優雅さを示すために、Python では 1 行のコードでサーバーを起動できる例がよく挙げられました。
リーリー
SimpleHTTPServer は、BaseHTTPServer モジュールのテスト メソッドをエントリ ポイントとして使用します。
リーリー
前の分析によると、httpserver サービスを使用するには、BaseHTTPRequestHandler を継続し、イントロスペクション メソッドを提供するだけで済みます。
リーリー
リーリー
do_GET の次のステップは、顧客が要求したパスのファイル データを、copyfile メソッドを通じてバッファされた書き込み可能なファイルに書き込み、クライアントに送信することです。 3.list_directory 由此可见,处理客户端的请求,只需要使用 send_reponse, send_header 和 end_headers ,就能向客户端发送reponse。 4.自定义http服务 然后再定义一个CustomHTTPServer继承自HTTPServer,它接受CustomHTTPRequestHadnler作为自己的handler。简单的代码如下: 使用curl访问可以得到 控制台会打出访问的log。 从socket的建立,select的IO模式,再到Server和Handler的组合构建服务。我们已经熟悉了python的基本网络编程。python的web开发中,更多是使用WSGI协议。实现该协议的还有 uWSGI和gunicorn等库。相比那些库,python内部提供了一个wsgiref模块,实现了一个简单wsgi服务--simple_server。 接下来将会通过分析simple_server,更好的掌握WSGI协议。
SimpleHTTPServer模块还提供了list_directory方法,用于响应path是一个目录,而不是文件的情况。
def list_directory(self, path):
try:
list = os.listdir(path)
except os.error:
self.send_error(404, "No permission to list directory")
return None
list.sort(key=lambda a: a.lower())
f = StringIO()
displaypath = cgi.escape(urllib.unquote(self.path))
f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
f.write("<hr>\n<ul>\n")
for name in list:
fullname = os.path.join(path, name)
displayname = linkname = name
# Append / for directories or @ for symbolic links
if os.path.isdir(fullname):
displayname = name + "/"
linkname = name + "/"
if os.path.islink(fullname):
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
f.write('<li><a href="%s">%s</a>\n'
% (urllib.quote(linkname), cgi.escape(displayname)))
f.write("</ul>\n<hr>\n</body>\n</html>\n")
length = f.tell()
f.seek(0)
self.send_response(200)
encoding = sys.getfilesystemencoding()
self.send_header("Content-type", "text/html; charset=%s" % encoding)
self.send_header("Content-Length", str(length))
self.end_headers()
return f
定义一个CustomHTTPRequestHadnler继承自BaseHTTPRequestHandler。在其内实现do_GET 方法来处理get请求。
# -*- coding: utf-8 -*-
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
class CustomHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write("hello world\r\n")
class CustomHTTPServer(HTTPServer):
def __init__(self, host, port):
HTTPServer.__init__(self, (host, port), CustomHTTPRequestHandler)
def main():
server = CustomHTTPServer('127.0.0.1', 8000)
server.serve_forever()
if __name__ == '__main__':
main()
➜ ~ curl http://127.0.0.1:8000
hello world
➜ ~
127.0.0.1 - - [01/Jun/2015 11:42:33] "GET / HTTP/1.1" 200 -