python で echo サーバ作ってみた

echo サーバとは

  • クライアントから送られてきた文字列をそのまま返すサーバ
  • socket の勉強として作ってみた

実装

echo_server.py

  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     client_sock.send("server : %s \n" % msg)
 28     print "client : %s" % msg
 29 
 30 client_sock.close()
 31 
 32 sock.close()
 33 

簡単に説明してみる

  • 6行目:サーバ側のソケットを作成する
  • 7行目:サーバ側のソケットにIPアドレスとポート番号設定する
  • 8行目:クライアントからの接続を待つ
  • 12行目:クライアントからの接続を受けて、クライアント側のソケットを作成する
  • 18行目:クライアント側のソケットからのメッセージを受信する
  • 22行目:クライアント側のソケットへメッセージを送信する(27行目も同様)
  • 30行目:クライアント側のソケットを閉じる
  • 32行目:サーバ側のソケットを閉じる

もうちょっと説明してみる

  • socket([family [, type [, proto] ] ])
    • family:アドレスファミリを指定。デフォルトはAF_INET
    • type:ソケットタイプを指定。デフォルトはSOCK_STREAM
    • proto:プロトコル番号を指定。通常省略するか0を指定
    • 戻り値:ソケットオブジェクト
  • bind(address)
    • address:(host, port) のペアを指定
    • 戻り値:なし。エラー時は例外を発生させる(多分ね)
  • listen(backlog)
    • backlog:接続キューの最大の長さを指定
    • 戻り値:なし。エラー時は例外を発生させる(多分ね)
  • accept()
    • 戻り値:(conn, address) のペアを返す
      • conn:接続を通じてデータの送受信を行うための新しいソケットオブジェクト
      • address:接続先でソケットに bind しているアドレス
  • recv(bufsize [, flags])
    • bufsize:受信する最大バイト数を指定
    • flags:デフォルトは0。値の意味は参考リンクのrecv(2)を参照
    • 戻り値:受信した文字列
  • send(string [, flags])
    • string:送信する文字列
    • flags:デフォルトは0。値の意味は参考リンクのrecv(2)を参照
    • 戻り値:送信した文字列のバイト数
  • close()
    • 戻り値:なし。エラー時は例外を発生させる(多分ね)

実行

サーバ側

$ python echo_server.py 
waiting for connection...
connection start
client : this
client : is
client : test
client : message
connection end

クライアント側

$ telnet localhost 8080
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying fe80::1...
telnet: connect to address fe80::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
server : connection start 

this
server : this 
is
server : is 
test
server : test 
message
server : message 

server : connection end 

Connection closed by foreign host.

まとめ

  • socket を使った通信の流れが大まかに理解できた

参考