pikesaku’s blog

個人的なプログラム勉強メモです。記載内容について一切の責任は持ちません。

Pythonネットワークプログラミング勉強コード

簡易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
$