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

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

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

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

Q&A

解決済

2回答

11531閲覧

Pythonでクライアントとサーバーのシステムを作っていて、複数回メッセージを送ることができないです。

sadfa

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/05/21 12:02

前提・実現したいこと

初めて質問します。
クライアントとサーバーのシステムを作っていて、何回もクライアント側からメッセージを送れるようにしたいです

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

2回目に文字を打つと

client.py", line 24, in <module> receive_msg = sock.recv(BUFSIZE) ConnectionAbortedError: [WinError 10053] 確立された接続がホスト コンピューターのソウトウェアによって中止されました。 と出てしまいます。 24行目はreceive_msg = sock.recv(BUFSIZE)です。

該当のソースコード

Python

1 2クライアント側 3# -*- coding: utf-8 -*- 4 5import socket 6 7#接続先ホストの名前(あるいはIPアドレス) ローカルホスト 8HOST='127.0.0.1' 9#接続先ホストのポート番号 10PORT = 50001 11#ソケットから受信するデータのバッファサイズ 12BUFSIZE = 4096 13 14#ソケットの作成 15sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 16try: 17 #サーバへの接続 18 sock.connect((HOST,PORT)) 19 flag = True 20 while flag: 21 #メッセージを入力 22 mesg=input('input message :')#この行を加えた 23 #バイトコード化してデータ送信 24 sock.send(mesg.encode()) 25 #データを受信 26 receive_msg = sock.recv(BUFSIZE) 27 print(receive_msg) 28 if mesg=='end': 29 flag = False 30finally: 31 #接続のクローズ 32 sock.close() 33print('end') 34 35 36サーバー側 37# -*- coding: utf-8 -*- 38 39import socket 40 41#サーバのホスト名(あるいはIPアドレス) 42HOST='127.0.0.1' 43#ポート番号 44PORT = 50001 45#接続の最大数 46BACKLOG = 10 47#ソケットから受信するデータのバッファサイズ 48BUFSIZE = 4096 49 50print('try socket') 51#ソケットを作成する 52sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 53print('try connect') 54 55try: 56 #作成したソケットにアドレスとポート番号を設定 57 sock.bind((HOST , PORT)) 58 sock.listen(BACKLOG) 59 while True: 60 #clientからの接続を開始 61 conn, address = sock.accept() 62 try: 63 #recv:ソケットからデータを受信 64 b_msg = conn.recv(BUFSIZE) 65 #バイトコードが送られてくるのでデコードする 66 msg = b_msg.decode('utf-8') 67 print('receive msg:'+ msg) 68 #ソケットにデートを送信 69 conn.send(b'you sent"' + b_msg + b'"') 70 finally: 71 #接続のクローズ 72 conn.close() 73finally: 74 #接続のクローズ 75 sock.close() 76print('end') 77 78

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

原因: サーバー側で、一回受信・返信した後に接続を閉じてます。
処理を追ってみてください。

python

1 while True: 2 #clientからの接続を開始 3 conn, address = sock.accept() 4 try: 5 #recv:ソケットからデータを受信 6 b_msg = conn.recv(BUFSIZE) 7 #バイトコードが送られてくるのでデコードする 8 msg = b_msg.decode('utf-8') 9 print('receive msg:'+ msg) 10 #ソケットにデートを送信 11 conn.send(b'you sent"' + b_msg + b'"') 12 finally: 13 #接続のクローズ 14 conn.close()
- clientからの接続を開始 - recv:ソケットからデータを受信 - バイトコードが送られてくるのでデコードする - ソケットにデートを送信 - 接続のクローズ <-- 原因

解決策: close の前に読出~返信のループを組む。

- clientからの接続を開始   (ここを繰り返す) - recv:ソケットからデータを受信 - バイトコードが送られてくるのでデコードする - ソケットにデートを送信 - 接続のクローズ

接続の最大数は10 となっていますが、現在のコードで扱える接続は一つのみです。
同時接続を考える場合は、スレッドを使う等の方法を別途検討してください。


追記: send/recv ですが、これらはデータの送受信を保証しない為、問題になる事があります。
例えば send() の説明ではこのように説明されてます。(recv()も同様)

戻り値として、送信したバイト数を返します。アプリケーションでは、必ず戻り値をチェックし、全てのデータが送られた事を確認する必要があります。データの一部だけが送信された場合、アプリケーションで残りのデータを再送信してください。 ソケットプログラミング HOWTO に、さらに詳しい情報があります。

実際にはこのような処理を自分で書くことは稀で、
より高水準なライブラリやフレームワークを使います。

  • socketモジュールの sendall や makefileとread について調べてみてください。
  • 他: socketserver フレームワーク 同時接続の場合についてもサンプルコードあり。

投稿2020/05/21 13:13

編集2020/05/21 13:26
teamikl

総合スコア8760

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

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

sadfa

2020/05/21 13:35

できました。ありがとうございます
sadfa

2020/05/21 13:38

ベストアンサーした後で申し訳ないのですが、サーバー側はアナコンダプロンプトで、クライアント側はspyderで実行していて、 両方をspyderで実行しようとすると、サーバー側を起動した後にクライアント側を実行できないのですが、何か方法はありますでしょうか?
teamikl

2020/05/21 14:01 編集

生憎と spyder はあまり使ったことがないので、実行環境についてはわかりません。 IDEであれば実行時の設定で複数のバックグランドジョブを実行できるか、 対応していなければ、プラグインの管轄になりますね。 サーバーをプロンプトで実行しておくのが無難だと思います。 スクリプトで対応できること、 毎回サーバーを起動・終了してもよいのなら、一回の実行操作により サーバー起動 → クライアントの実行を行う事は可能です。(そのようにコードを書く必要はあります)
sadfa

2020/05/21 14:51

分かりました。ありがとうございます。
guest

0

クライアント側の Socket を毎回接続し閉じるようにすると良いのではないでしょうか?

ソケットプログラミング HOWTO — Python 3.8.3 ドキュメント

だが、以降の転送にもそのソケットを使い回すつもりなら、ソケットに EOT など 存在しない ことを認識する必要がある。もう一度言おう: ソケットの send や recv が 0 バイト処理で返ってきたなら、その接続は終わっている。終わって いない なら、いつまで recv を待てばいいかは分からない。

それが嫌であれば、もう少し、工夫が必要そうです。

投稿2020/05/21 13:33

Yasumichi

総合スコア1773

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問