質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2992閲覧

socketでsendするときに引数の変換に失敗してしまいます。

t4gforce

総合スコア5

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/30 12:04

編集2020/08/01 04:26

前提・実現したいこと

python3でsocketのsendの引数に、bytes型を指定したいのですが、変換に失敗します。

発生している問題・エラーメッセージ

'utf-8' codec can't decode byte 0x83 in position 1: invalid start byte

該当のソースコード

エラーが起きているソースコードを追記させていただきます。
以下のリンクのコードを参考にしています。
https://github.com/AllGloryToTheHypnotoad/Black-Hat-Python/blob/master/BHP-Code/Chapter2/bhnet.py
一つのファイルの実行時に指定されたオプションで、サーバ側とクライアント側の動作が変わる様になっています。
サーバとして動作させる場合は、python ./bhnet.py -l -p 9999 -c とオプションを指定し、
そのサーバに接続する際は、python ./bhnet.py -t localhost -p 9999 とオプションを指定して起動しています。

・encoding='utf-8'を追加し、再度更新しました

python

1# coding:utf-8 2 3# filename : bhnet.py 4 5import sys 6import socket 7import getopt 8import threading 9import subprocess 10 11import traceback 12 13# global 14listen = False 15command = False 16upload = "" 17execute = "" 18target = "" 19upload_destination = "" 20port = 0 21 22 23# コマンドを実行し出力を返す 24def run_command(command): 25 command = command.rstrip() 26 27 try: 28 output = subprocess.check_output( 29 command, stderr=subprocess.STDOUT, shell=True) 30 output = output.decode(encoding="shift-jis") 31 # output = output.decode(encoding="utf-8") # 'utf-8' codec can't decode byte 0x83 in position 1: invalid start byte 32 except Exception as e: 33 output = str(e) 34 output += "\r\n" 35 output += "Failed to execute command.\r\n" 36 37 return output 38 39 40# クライアントが送ったデータを処理する 41def client_handler(client_socket): 42 global upload 43 global execute 44 global command 45 46 # uploadが指定されたときの動作 47 if len(upload_destination): 48 file_buffer = "" 49 50 while True: 51 data = client_socket.recv(1024).decode(encoding='utf-8') 52 53 if not data: 54 break 55 else: 56 file_buffer += data 57 58 try: 59 file_descriptor = open(upload_destination, "wb") 60 file_descriptor.write(file_buffer) 61 file_descriptor.close() 62 63 client_socket.send( 64 b"Successfully saved file to %s\r\n" % upload_destination) 65 except Exception: 66 client_socket.send( 67 b"Failed saved file to %s\r\n" % upload_destination) 68 69 # コマンドの実行(execute)が指定されたときの動作 70 if len(execute): 71 output = run_command(execute) 72 client_socket.send(output.encode(encoding='utf-8')) 73 74 # commandが指定された場合はシェルとして動作する 75 if command: 76 while True: 77 propmt = "<BHP:#> " 78 client_socket.send(propmt.encode(encoding='utf-8')) 79 80 cmd_buffer = "" 81 while "\n" not in cmd_buffer: 82 cmd_buffer += client_socket.recv(1024).decode(encoding='utf-8') 83 response = run_command(cmd_buffer) 84 85 client_socket.send(response.encode(encoding='utf-8')) 86 87 88# 受信用の関数 89def server_loop(): 90 global target 91 global port 92 93 # ターゲットの指定がなければすべてのアクセスを受け付ける 94 if not len(target): 95 target = "0.0.0.0" 96 97 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 98 server.bind((target, port)) 99 100 server.listen(5) 101 102 while True: 103 client_socket, addr = server.accept() 104 105 # クライアントの処理を行うスレッドの作成 106 client_thread = threading.Thread( 107 target=client_handler, args=(client_socket,)) 108 client_thread.start() 109 110 111# クライアントとしてデータを送信する関数 112def client_sender(buffer): 113 114 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 115 116 try: 117 client.connect((target, port)) 118 print("connected!") 119 120 if len(buffer): 121 client.send(buffer.encode(encoding='utf-8')) 122 123 while True: 124 recv_len = 1 125 response = "" 126 127 while recv_len: 128 data = client.recv(4096).decode(encoding='utf-8') 129 recv_len = len(data) 130 response += data 131 132 if recv_len < 4096: 133 break 134 135 print(response) 136 137 buffer = input("") 138 buffer += "\n" 139 140 client.send(buffer.encode(encoding='utf-8')) 141 except Exception as e: 142 print(e) 143 print(traceback.format_exc()) 144 print("[*] Exception! Exiting.") 145 client.close() 146 147 148def main(): 149 global listen 150 global port 151 global execute 152 global command 153 global upload_destination 154 global target 155 156 if not len(sys.argv[1:]): 157 sys.exit(0) 158 159 try: 160 opts, args = getopt.getopt( 161 sys.argv[1:], 162 "hle:t:p:cu", 163 ["help", "listen", "execute=", "target=", 164 "port=", "command", "upload="] 165 ) 166 except getopt.GetoptError as err: 167 print(str(err)) 168 for o, a in opts: 169 if o in ("-l", "--listen"): 170 listen = True 171 elif o in ("-e", "--execute"): 172 execute = a 173 elif o in ("-c", "--commandshell"): 174 command = True 175 elif o in ("-u", "--upload"): 176 upload_destination = a 177 elif o in ("-t", "--target"): 178 target = a 179 elif o in ("-p", "--port"): 180 port = int(a) 181 else: 182 assert False, "Unhandled Option" 183 184 # クライアントとして動作 185 if not listen and len(target) and port > 0: 186 buffer = sys.stdin.read() 187 client_sender(buffer) 188 189 # サーバとして動作 190 if listen: 191 print("...") 192 server_loop() 193 194 195main()

試したこと

プログラムのコードすべてとTraceback全文を追記しました。
長くなってしまいますが、よろしくお願いいたします。

再度更新いたしました
重ねてお願いとなってしまいますが、よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Python 3.8.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2020/07/30 13:20

どの部分で発生したか追えるように、エラーは全文(Traceback)を記載ください。 また、できればクライアント側の完全なコードも提示ください。
t4gforce

2020/07/30 15:25

クライアント側とサーバ側のコードと、Tracebackをすべて追記しました。 引き続きよろしくお願いいいたします。
bsdfan

2020/08/01 13:33

subprocess で実行しているコマンドの出力のエンコードはUTF-8なのでしょうか? それがSJISなだけでは?
t4gforce

2020/08/01 16:48

教えていただきありがとうございます。 コマンドの出力がshift-jisなだけのようですので、subprocess.check_output()の戻り値の文字コードによって処理を変更するようにしようと思います。
guest

回答2

0

ベストアンサー

サーバ側のエラーについてですがcmd_buffer変数がbyte型なのにstr型を足しているため提示エラーが発生しています。
どのように修正すべきかはコードの意図が不明なので分かりませんが、型を統一しないといけません。

クライアント側のエラーは再現しませんでしたが、サーバとクライアントでのエンコーディングの違いが原因だと思われます。
コード上の.encode(), .decode()関数にてencoding='utf-8'と明示的にエンコーディングを指定すると解消すると思われます。

投稿2020/07/31 00:57

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t4gforce

2020/08/01 04:26

教えていただきありがとうございます。 サーバ側エラーはすべてstr型で統一することで動作しました。 他の箇所も.encode()/.decode()にencoding='utf-8'とすることで動作したのですが、 ソースコードの30行目だけencoding="shift-jis"としなければ、 'utf-8' codec can't decode byte 0x83 in position 1: invalid start byte というエラーが出てしまいます。 重ねてお願いとなってしまいますが、ソースコードを更新しましたので、このエラーについて詳しく教えていただけないでしょうか。
can110

2020/08/01 12:55

>ソースコードの30行目だけencoding="shift-jis"としなければ、 それで正常に動作するのであれば、そのままでよいです。 subprocess.check_output関数の戻り値の標準出力結果の文字列(実際はバイト列)の文字コードは 環境依存だったはずなので、その部分の.decode()は環境にあわせる必要があります。
t4gforce

2020/08/01 16:47

詳しく教えていただきありがとうございました。 subprocess.check_output()の戻り値の文字コードによってdecode()の文字コード指定を変更するようにしようと思います。
guest

0

encoding="shift-jis" ではどうでしょうか

投稿2020/07/30 13:08

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問