chinda_fall_desu’s diary

竹内豊の日記

ヒューマンコンピューターインターフェースをもっと知りたいなー

pythonでsocketを使って通信を行う③ (コマンドの実行)

今回は前回までのコードを再び改良し、コマンドを実行できるようにする。


準備
コマンドの実行にはsubprocessモジュールを用いる。
下記のようにして、コマンドを実行できる。

import subprocess
com=subprocess.run("dir", stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
print(com.stdout.decode('cp932'))
print(com.stderr.decode('cp932'))
> python .\30.py
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 40BE-398B です

 C:\-----------------\02 のディレクトリ

2020/01/12  21:27    <DIR>          .
2020/01/12  21:27    <DIR>          ..
2020/01/12  21:28               549 30.py
2020/01/12  21:27                24 sample.txt
               2 個のファイル                 573 バイト
               2 個のディレクトリ   5,052,829,696 バイトの空き領域


上記のモジュールを使って前回までのコードを改良する。
ソースコード
・サーバ側

import socket
import subprocess

bind_host="0.0.0.0"
bind_port=50000

server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_host, bind_port))
server.listen(5)
print("host: "+bind_host)
print("port: "+str(bind_port))

while True:
    client, addr=server.accept()
    print("from:"+ addr[0]+" "+str(addr[1]))
    while True:
        print("waiting for his response...")
        rec=client.recv(1024)
        com=subprocess.run(rec.decode('utf-8'), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        # print(rec.decode('utf-8'))
        client.send(com.stdout)
        client.send(com.stderr)

        if len(rec)==0:
            client.close()
            break

・クライアント側

import socket
target_host="(サーバ側のIPアドレス)"
target_port=50000
client=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
while True:
    com=input("command: ")
    client.send(com.encode('utf-8'))
    rec=client.recv(4096)
    print(rec.decode('cp932'))


実行結果
・サーバ側

> python .\server.py
host: 0.0.0.0
port: 50000
from:(クライアント側のIPアドレス)(クライアント側のポート番号)
waiting for his response...
waiting for his response...
waiting for his response...
waiting for his response...
waiting for his response...
waiting for his response...

・クライアント側

> python .\client.py
command: dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 40BE-398B です

 C:\---------------------\01 のディレクトリ

2020/01/12  21:34    <DIR>          .
2020/01/12  21:34    <DIR>          ..
2020/01/12  21:16                24 02.txt
2020/01/12  21:16                24 sample.txt
2020/01/12  21:14               724 server.py
               3 個のファイル                 772 バイト
               2 個のディレクトリ   5,051,006,976 バイトの空き領域

command: type sample.txt
hello
i'm from Canada

command: copy sample.txt copy.txt
        1 個のファイルをコピーしました。

command: dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 40BE-398B です

 C:\---------------------\01 のディレクトリ

2020/01/12  21:34    <DIR>          .
2020/01/12  21:34    <DIR>          ..
2020/01/12  21:16                24 02.txt
2020/01/12  21:16                24 copy.txt
2020/01/12  21:16                24 sample.txt
2020/01/12  21:14               724 server.py
               4 個のファイル                 796 バイト
               2 個のディレクトリ   5,049,970,688 バイトの空き領域

command: type copy.txt
hello
i'm from Canada

command:


解説
・クライアント側からサーバ側にコマンドを送信し、サーバ側で実行されたコマンドの実行結果をクライアント側に返している。
・クライアント側はこれによってサーバ側のディレクトリの中身、ファイルの中身を見ることができる。


(間違い等あればコメントよろしくお願いいたします。)