簡易tcpサーバ
動作
・受信データを16進数でクライアントに返す。
・接続開始、終了情報をサーバ側コンソールに出力する。
コード
# -*- coding: utf-8 -*- import sys import socket import threading CS = 'utf-8' PORT = sys.argv[1] # PORTはstr型(Python3) # isdigitメソッドで数字が判定 if not PORT.isdigit(): print('invaild argment') exit(1) def do_server(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('0.0.0.0', int(PORT))) server.listen(5) while True: client_socket, addr = server.accept() # targetに受信データを処理する関数オブジェクト(client_hander)を指定。 # 実行結果を引数にするわけではない為、client_handerの後に()はつけない。 client_addr = str(addr[0]) + ':' + str(addr[1]) print('Connected from: ' + client_addr) client_thread = threading.Thread(target=client_handler, args=(client_socket,client_addr)) client_thread.start() def client_handler(client_socket,client_addr): while True: # dataにクライアント送信データが格納(byte型)される。 data = client_socket.recv(1024) if not data: # 切断時処理 # ncコマンドで接続しCTRL+Cを送信するとクライアントはFINパケット # を送信しTCP接続は切れる。dataにはbyte型の空データ(0x00)が格納される。 # TCP1接続が切れた状態で、client_socket.recvが実行されるとdataに # 空データが格納される。その為、LOOPを抜ける必要がある。 print('Dosconnected from: ' + client_addr) break else: # 受信データを16進数にしたものをクライアントに返す r = 'You send following data: ' for i in data: # byte型にイテレータ処理をするとint型になる。 # int型のiを、formatメソッドでstr型に変換 r += 'x{0:02x}'.format(i) # クライアントにデータを返す時は、byte型にして送る。 r += '\n' client_socket.send(r.encode(CS)) client_socket.close() def main(): do_server() if __name__ == '__main__': main()
実行例
クライアント側操作
①ncコマンドでサーバに接続
②"abc"を入力してEnter
③何も入力せずEnter
④CTRL+C
サーバ側出力
$ python ./tcp_srv.py 10001 Connected from: 127.0.0.1:59653 Dosconnected from: 127.0.0.1:59653
クライアント側出力
$ nc 127.0.0.1 10001 abc You send following data: x61x62x63x0a You send following data: x0a ^C $