応用プログラミング ex2 演習課題
後半の演習の進め方については、後半第1回の0.1 はじめにをご覧ください。
1. sys.argv でコマンドライン引数を使う
1-1. argv.py
- 以下の Pythonコード argv.py を自分のPCの適当なフォルダ/ディレクトリにダウンロードしなさい。
- argv.py を適当なコマンドライン引数と共に実行し、その動作を確認しなさい。
- argv.py を修正し、コマンドライン引数として与えられた整数を全て加算して出力する add.py を作成しなさい。ただし、引数に整数値に変換できない文字列が与えられた場合の処理は考えなくてもよい。
- argv.py
# argv.py import sys args = sys.argv argc = len(args) print('args =',args) print('len(args) =', argc) for i in range(argc): print('args[{0}] = {1}'.format(i, args[i]))
実行例:
$ python add.py 0 $ python add.py 1 3 9 13 $ python add.py -1 3 -9 -7 $ python add.py 1 2 -34 56 -78 90 37
1-2. echoServer-argv.py
- echoServer.py を修正し、コマンドライン引数でサーバのポート番号を指定できる echoServer-argv.py を作成しなさい。
- ただし、引数が与えられない場合はポート番号を 50007 とし、また、2つ以上の引数が与えられた場合はコマンドの利用方法を表示して終了すること。
実行例:(^C は Control+C での強制終了)
$ python echoServer-argv.py port = 50007 ^C $ python echoServer-argv.py 1234 port = 1234 ^C $ python echoServer-argv.py 1234 5678 Usage: echoServer-argv.py [port]
サーバプログラムを続けて実行すると、
OSError: [Errno 98] Address already in use
のようなエラーが表示され、サーバがうまく立ち上がらないことがあります。 これは、以前に実行したサーバプログラムで利用したアドレスやポートが、プログラム終了後もすぐにはOSから開放されずに再利用できないことが原因です。 また、TAチェック用のリモート実習室環境 rp-linux では、複数のユーザーが同じPCにログインすることがあるため、同じPC上の他のユーザーやプログラムがすでに利用しているポートを利用することができません。
このような場合は、他のポート番号を利用して新しいサーバプログラムを実行すると、以前のものと衝突せずに起動することができます。
また、前者の問題(OSからポートが開放されない)であれば、作成したソケットに対して次のようなオプションを設定することでもこの問題を回避することができます。
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
1-3. echoClient-ex.py
- echoClient.py を修正し、コマンドライン引数でサーバのホスト名(IPアドレス)、送信文字列、ポート番号の順に指定できるプログラム echoClient-ex.py を作成しなさい。
- ただし、最後の引数となるポート番号の指定は省略できるものとし、ポート番号が引数として与えられない場合はポート番号を 50007 とする。
- また、引数が2つ未満でホスト名と送信文字列の両方が与えられない場合、または、4つ以上の引数が与えられた場合はコマンドの利用方法を表示して終了すること。
- echoClient-ex.py を利用して、rp-linux 環境から IPアドレス 133.83.80.113 の 5000 番ポートのサーバーへ、自分の学籍番号を含む適当な文字列を送信しなさい。
- 133.83.80.113 で実行されている echoServer.py の実行結果は、Teams 上の会議で画面共有として常時表示しておきます。
実行例:(この例では接続先サーバは送信文字列を2倍して返信しています)
$ python echoClient-ex.py localhost あいうえお 5007 localhost あいうえお 5007 Send あいうえお Received あいうえおあいうえお $ python echoClient-ex.py 127.0.0.1 hello 5007 127.0.0.1 hello 5007 Send hello Received hellohello $ python echoClient-ex.py 127.0.0.1 hello 127.0.0.1 hello 50007 Send hello Received hellohello $ python echoClient-ex.py localhost Usage: echoClient-ex.py <server> <message> [port] $ python echoClient-ex.py localhost hello 5007 123 Usage: echoClient-ex.py <server> <message> [port]
2. 繰り返しの送受信
- echoServer.py は、クライアントとの通信を1回行うごとにプログラムの実行を終了するため、続けて通信するためには再び echoServer.py を起動し直す必要がある。
- echoServer.py を修正し、1つのクライアントとの送受信を完了してもプログラムを終了せず、再び受信待機(Listen)状態に復帰して引き続き次のクライアントと通信を行うことができるプログラム echoServer-ex.py を作成しなさい。
- echoServer-ex.py を実行し、そのサーバのIPアドレスとポート番号をTAに伝え、TAの指示に従って質問に回答しなさい。
実行例:(^C は Control+C での強制終了)
$ python echoServer-ex.py 5001 port = 5001 Connected by ('127.0.0.1', 57680) Received Hello Send Hello Connected by ('127.0.0.1', 57683) Received HelloHello Send HelloHello Connected by ('127.0.0.1', 57686) Received Hello World Send Hello World ^C
3. ファイルの内容を送信するサーバ htServer.py
- htServer.py は、クライアントから 'GET' というコマンド(文字列)を受け取ると、htServer.py と同じディレクトリにあるテキストファイル(例えば、server.txt)の内容を返信し、それ以外のコマンドを受け取ると 'not a command' のようなメッセージを返信する。
- このようなサーバプログラムhtServer.py を作成し、適当なクライアントプログラムで動作を確認しなさい。
テキストファイルの例: server.txt
- server.txt
これは server.txt ファイルの中身です
実行例: htServer.py
(aprog) t190900@s01cd0542-161:~/apro$ python htServer.py 50001 port = 50001 Connected by ('127.0.0.1', 55810) Received GET これは server.txt ファイルの中身です Connected by ('127.0.0.1', 55824) Received get get is not a command
実行例: echoClient-ex.py
(aprog) t190900@s01cd0542-161:~/apro$ python echoClient.py localhost GET 50001 localhost GET 50001 Send GET Received これは server.txt ファイルの中身です (aprog) t190900@s01cd0542-161:~/apro$ python echoClient.py localhost get 50001 localhost get 50001 Send get Received get is not a command