2014年8月3日日曜日

開発環境

Head First C ―頭とからだで覚えるCの基本(David Griffiths (著)、Dawn Griffiths (著) 中田 秀基(監訳)(翻訳)、木下 哲也 (翻訳)、オライリージャパン)の11章(ソケットとネットワーキング(127.0.0.1という場所はない)、長いエクササイズ(p.480)をpythonで考えてみる。

長いエクササイズ(p.480)

コード(BBEdit, Emacs)

sample480.py

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import sys
import socket
import signal

def error(msg):
    print("{0}: {1}".format(msg, err))
    sys.exit(1)

def say(s):
    try:
        data = s.encode('utf-8')
        count = connect_d.send(data)
        if count != len(data):
            raise Exception()
    except Exception as err:
        raise Exception('クライアントの通信エラー: {0}'.format(err))
        
def handle_shutdown(sig, stack_frame):
    if listener_d != None:
        listener_d.close()
    print('さようなら!', file=sys.stderr)
    sys.exit(0)

try:
    signal.signal(signal.SIGINT, handle_shutdown)
except Exception as err:
    error('割り込みハンドラを設定できません。{0}'.format(err))

port = 30000
host = 'localhost'
listener_d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    listener_d.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except Exception as err:
    error('ソケットに再利用オプションを設定できません。{0}'.format(err))

listener_d.bind((host, port))

try:
    listener_d.listen(10)
except Exception as err:
    error('接続待ちできません。{0}'.format(err))

print("接続を待っています。")

while True:
    try:
        connect_d, addr = listener_d.accept()
    except Exception as err:
        error('第2のソケットを開けません。{0}'.format(err))
    try:
        say('Knock!Knock!\r\n')
        data = connect_d.recv(255)
        if data[:12] == b"Who's there?":
            try:
                say('Oscar\r\n')
                data = connect_d.recv(255)
                try:
                    if data[:10] == b'Oscar who?':
                        say('Oscar silly question, you get a silly answer\r\n')
                    else:
                        say('「Oscar who?」と入力しなければいけません!\r\n')
                except Exception as err:
                    print(err, file=sys.stderr)
            except Exception as err:
                print(err, file=sys.stderr)
        else:
            say("「Who's there?」と入力しなければいけません!\r\n")
    except Exception as err:
        print(err, file=sys.stderr)
    connect_d.close()

入出力結果(Terminal, IPython)

サーバー

$ ./sample480.py
接続を待っています。
  C-c C-cさようなら!
$ ./sample480.py
接続を待っています。
  C-c C-cさようなら!
$

クライアント

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock!Knock!
Who's there?
Oscar
Oscar who?
Oscar silly question, you get a silly answer
Connection closed by foreign host.

Process telnet-127.0.0.1 30000 exited abnormally with code 1

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock!Knock!
Who?
「Who's there?」と入力しなければいけません!
Connection closed by foreign host.

Process telnet-127.0.0.1 30000 exited abnormally with code 1

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock!Knock!
Who's there?
Oscar
Oscar?
「Oscar who?」と入力しなければいけません!
Connection closed by foreign host.

Process telnet-127.0.0.1 30000 exited abnormally with code 1

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock!Knock!
Who?
「Who's there?」と入力しなければいけません!
Connection closed by foreign host.

Process telnet-127.0.0.1 30000 exited abnormally with code 1

0 コメント:

コメントを投稿