ネットワークのお勉強してみた
やること
- telnet をつかって http リクエストを発行する
- python で socket 関数を利用して http クライアントを実装する
- python で socket 関数を利用して http サーバを実装する
1. telnet してみる
- なにはともあれやってみる
- 対象はヤフーのトップページ
$ telnet www.yahoo.co.jp 80 Trying 203.216.247.249... Connected to www.ya.gl.yahoo.co.jp. Escape character is '^]'. GET /index.html HTTP/1.0 HTTP/1.1 200 OK Date: Wed, 14 Apr 2010 16:25:50 GMT P3P: policyref="http://privacy.yahoo.co.jp/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV" Cache-Control: no-cache Cache-Control: no-store, must-revalidate Expires: -1 Pragma: no-cache X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds Cache-Control: private Connection: close Content-Type: text/html; charset=utf-8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> - 省略 - </html> Connection closed by foreign host.
- 通信の流れ
2. http client を作ってみる
- http_client.py
1 import socket 2 3 host = socket.gethostbyname('www.yahoo.co.jp') 4 port = 80 5 6 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 sock.connect((host, port)) 8 sock.send("GET /index.html HTTP/1.0 \n\n") 9 10 msg = sock.recv(1024) 11 sock.close() 12 13 print msg 14
- 実行する
$ python http_client.py HTTP/1.1 200 OK Date: Wed, 14 Apr 2010 16:47:06 GMT P3P: policyref="http://privacy.yahoo.co.jp/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV" Cache-Control: no-cache Cache-Control: no-store, must-revalidate Expires: -1 Pragma: no-cache X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds Cache-Control: private Connection: close Content-Type: text/html; charset=utf-8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-style-type" content="text/css"> <meta http-equiv="content-script-type" content="text/javascript"> <meta name="description" content="日本最大級のポータルサイト。検索、オークション、ニュース、メール、コミュニティ、ショッピング、など80
- プログラムの流れ
- socket を生成する
- 指定した host, port に接続する
- 接続先にメッセージを送る
- 接続先からのメッセージを受け取る
- socket を閉じる
3. http server を作ってみる
- ソース
1 import socket 2 3 host = socket.gethostbyname('localhost') 4 port = 8080 5 6 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 sock.bind((host, port)) 8 sock.listen(1) 9 10 print 'waiting for connection...' 11 12 (client_sock, client_addr) = sock.accept() 13 14 client_sock.send("server : connection start \n\n") 15 print 'connection start' 16 17 while True: 18 msg = client_sock.recv(1024) 19 msg = msg.rstrip() 20 21 if msg == "": 22 client_sock.send("server : connection end \n\n") 23 print 'connection end' 24 break 25 26 else: 27 print "client : %s" % msg 28 29 client_sock.close() 30 31 sock.close() 32
- 実行して telnet で確認する
server 側
$ python http_server.py waiting for connection... connection start client : this client : is client : server client : test connection end
client 側
$ telnet localhost 8080 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. server : connection start this is server test server : connection end Connection closed by foreign host.
- プログラムの流れ
- socket を生成する
- bind で待ち受ける host, port を指定する
- listen で待ち受けを開始する
- accept で接続待ちをする
- recv で クライアントから送られてくるメッセージを受け取る
- メッセージが空でなければ出力、空の場合はループを抜けてクライアントとの接続を切る
- socket を閉じる
まとめ
- telnet で http リクエストを送ることができた
- エラー処理などはしていないが、簡単な http クライアントとサーバが作れた
- socket 関数を使って開発したことで、通信のやりとりが何となくわかったと思う