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

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

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

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Python

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

Q&A

1回答

2359閲覧

socket通信中にプラグラムが停止してしまう(終了はしない)

ramin

総合スコア34

Python 3.x

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Python

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

0グッド

0クリップ

投稿2022/06/03 15:54

編集2022/06/04 08:43

pythonのsocketライブラリでtcp通信プログラムを作成しました。
サーバーから毎秒データを送っているのですが、突然何のエラーもなくclient.pyのif not rcv_dataでプログラムが停止してしまいます。
try exceptでもエラーが出ていないため、原因が全く分からないのですが、何か原因としてありそうなことを教えていただきたいです。

環境はAWS EC2 AmazonLinux2でcloud9で動かしています。
AWS EC2のモニタリングでCPU使用率を確認してみましたが、停止時間中でもそれ以外の時間より高いというわけではなく10~20%程度でした。

python

1# client.py 2socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 3socket_client.connect(("localhost", 8080)) 4while True: 5 try: 6 rcv_data = socket_client.recv(1024) 7 logger.info("{} recv {}".format(datetime.utcnow(), rcv_data.decode())) 8 if not rcv_data: 9 logger.info("Disconnect") 10 break 11 else: 12 logger.info("{} {}".format(datetime.utcnow(), "send ok")) 13 socket_client.send("ok".encode()) 14 except: 15 traceback.print_exc() 16 17 18# 実際に動かすと数時間後に下記のようにif not rcvの処理で4時間以上停止している 192022-06-03 00:03:00.621 recv test 202022-06-03 00:03:00.848 send ok 21... 222022-06-03 02:03:05.621 recv test 232022-06-03 06:42:57.848 send ok 24

python

1#server.py 2sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 3sock.bind(("localhost", 8080)) 4sock.listen() 5client,remote_addr = sock.accept() 6while True: 7 client.send("test".encode()) 8 rcv_data = client.recv(1024) 9 time.sleep(1)

このほかにthreadingでwhile Trueの無限ループで3秒ごとにログを出力する関数も動かしているのですが、そちらも止まっていました。
プログラム全体が止まってしまっていると思うのですが、これはsocketライブラリによって引き起こされているのでしょうか?

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

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

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

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

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

guest

回答1

0

クライアント側のwhileが一重ループなので、一度受信が完了するとbreakでwhileを抜けて終わってしまいます。client.pyでは処理が終わっただけで、ソケットの切断はされていません。

続けてデータを処理するにはtryの後にもう一つwhileがいります。
ただし、これだと間髪入れずに次の処理をするので、何か条件分岐を加えた方がよいです。

補足:ソケットは切断するとめんどくさいので、プログラムの(異常)終了時だけ切断し、それまでは同じソケットを使い回した方がよいと考えます。

投稿2022/06/03 21:39

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ramin

2022/06/04 08:49 編集

回答ありがとうございます。 client.pyのbreakですが、if not recv_dataなのでサーバー側でソケットをクローズされない限りはelseを通って無限ループになるはずです。
退会済みユーザー

退会済みユーザー

2022/06/04 10:40 編集

手元で確認していないのでうろ覚えの経験の話ですが、 クライアントの処理は if not rcv_data:   一回のパケット(1024)の中身が空の場合 else:   何かのデータが送られた場合 です。 サーバの送信命令は、 client.send("test".encode()) が一回の通信分のデータです。2バイト=16ビットしかなく、一回のパケット(1024)に収まります。クライアントのrcv_dataはサーバが一回のソケット通信で送ろうとしたデータ("test")が送り終わったらNoneかFalseか""のようなデータがclientに届きます。(もし送ろうとしたデータが画像のような大きいものでしたら、一回のソケット通信で何回もパケットを送り、else側の処理を何度も繰り返して受信したデータを結合し続け、サーバが送り終わったらnot rcv_dataの方に流れてbreak、という流れになります、)ですので、今回のような小さいデータをサーバから送った場合、一度パケットを受信したら直ちにクライアントのelseに流れ、breakするだろうという考えです。 ただし、本当にそうかはprint("else")みたいなものを挟んでトレースしないとわかりません💦 補足:パケットはソケット通信で何度もやり取りする最大容量の決まったバケツ(ここではサイズを1024と定義)のようなイメージです。ソケット通信は、パケットを何度もやり取りする通信手法の名前、と理解しています。 --- https://qiita.com/shino_312/items/3c81ed8d8dfd0d53f25a にあるように、私も過去にサーバクライアントの継続した通信をする際にはSO_REUSEADDRを使ったような気がします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問