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

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

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

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

Q&A

解決済

1回答

1562閲覧

ひとつのプログラムでサーバーとクライアントを両持ちする方法(sockets)

FIC-d

総合スコア12

Python

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

0グッド

0クリップ

投稿2021/09/26 11:31

編集2021/09/27 06:54

前提・実現したいこと

pythonのsocketsモジュールを使って、送受信」ができるようなプログラムを作っています。サーバーのプログラムとクライアントのプログラムを両立させるためにはどうすればいいでしょうか。

該当のソースコード

python

1import socket 2import socketserver 3 4#サーバー 5class TCPHandler(socketserver.BaseRequestHandler): 6 def handle(self): 7 print(self.request.recv(1024).strip().decode()) 8 self.request.send(("hello world").encode("utf-8")) 9ip = socket.gethostbyname(socket.gethostname()) 10 11HOST = ip 12PORT = 34567 13socketserver.TCPServer.allow_reuse_address = True 14server = socketserver.TCPServer((HOST, PORT), TCPHandler) 15try: 16 server.serve_forever() 17except KeyboardInterrupt: 18 pass 19server = socketserver.TCPServer((HOST, PORT), TCPHandler) 20server.serve_forever() 21self.request.recv(1024).strip().decode() 22("hello world").encode("utf-8") 23 24#クライアント 25sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 26sock.connect((HOST,PORT)) 27sock.send(('Hello Raspberry').encode("utf-8")) 28receivedstr=sock.recv(1024) 29print(receivedstr.decode()) 30sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 31sock.connect((HOST,PORT)) 32receivedstr=sock.recv(1024)

引用:https://elsammit-beginnerblg.hatenablog.com/entry/2020/12/19/185338

試したこと

サーバーのプログラムとクライアントのプログラムを同じところに書きましたが。うまくいきません。

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

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

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

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

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

otn

2021/09/26 12:46

どういう処理をしたいのかを、日本語でちゃんと書きましょう。
AbeTakashi

2021/09/26 14:54

うまくいかないと言われても何が起きてるか分からないので、具体的に何がどううまくいかないのか?(例えばエラーメッセージが出てるなら、そのエラーメッセージを質問文内に含めるなど) またteratail初めたばかりだと思いますので、今一度こちらのページを参考にされて、質問文に必要な情報を追記してください。 参考) https://teratail.com/help/question-tips 現状だとちょっと答えが出そうにないというか、エスパーが出てくるのを頼るしかない状況です。 追記) なんとなくやりたいことは分かるのですが、サーバとクライアントまったく同じソースコードで動かそうとするのは無理があるかな?という気もしてます。Socket通信ならどっちから繋ぎににいくだけで、双方向のデータの送受信はできると思いますけど、あえてこういうことをされる意味がたぶん誰にも伝わらない気がしています。
FIC-d

2021/09/26 22:47

エラーメッセージが出るわけではありません
AbeTakashi

2021/09/27 01:50 編集

エラーメッセージが出ないということは分かりましたが、うまくいかないというだけではとにかく状況がわからなすぎて回答者に伝わりませんので、その辺の情報をもっと質問文に追記した方が良いと思いますよ。 上でも書きましたが、Socket通信は通常はどちらかがクライアント、どちらかがサーバーになって1つの接続で互いに送受信するのがわりと一般的だと思いますが、このプログラムはそれぞれがクライアントとサーバになって接続2本にしようとしてるように見受けられます。一般的な方法じゃないと思うので、otnさんも書いていますがどういう目的でどういう処理をしたいのか(なぜ、このような一般的な方法じゃないことをあえて選択しているのか?)も質問文内にしっかり記載した方がいいと思います。 質問文は追記や更新ができます。
FIC-d

2021/09/27 06:40

一般的なのは例えば何でしょうか?
AbeTakashi

2021/09/27 07:00

一般的な方法はすでに書いてます。参考サイトもその方法で書かれてるのに、なぜともに両方がクライアントとサーバーになる方法で通信を試みるのかがちょっと分かりません(確かにそういう実装が必要な場合もあるのですが、何となくですが必要がないのに実装しようとしてるように見えます) 軽くソースコード見た限りだとともに受信待ちになって、送信の処理までちゃんと進んでるのかな?とも思いますし、その辺もしっかり確認した方が良いのでは?とも思います。かつ、その点は質問文にもしっかり説明を入れた方が良いと思います。
FIC-d

2021/09/27 07:03

分かりました。ちょっと考えてみます。
guest

回答1

0

ベストアンサー

これまでのコメントでのやりとりの内容やソースコードを眺めてみて、なんとなくですがこういうことをしたいのかな?と思ったのが、両方とも任意のタイミングでデータを送信したり受け取ったりし、そのデータを任意のタイミングで非同期に処理したいのかな?という風に感じました(この説明を追記してほしかったことをコメントでお伝えしていたのですが、残念ながら出てこなかったのでこちらで勝手に解釈しました)。

であれば、たしかに両方ともクライアントとサーバの両機能を入れる実装をするパターンもありますが、前述の通りでバカ正直にやるとコネクションを2本張る必要があります。ポート番号を使い分けるなどの対策も必要で、おそらくクライアントとサーバまったく同じソースコードで動くというはやはり無理があるでしょう。

あと、Socket通信に関してはブロッキングで扱うかノンブロッキングで扱うかを考えないといけません。書かれているソースはおそらくブロッキングで扱っているので(pythonでソケットを扱ったことないので詳しくないのですが、server.serve_forever()の部分はブロッキングしてると思います)、キーを押した瞬間にサーバ機能は停止してクライアントだけの機能になると思われます。なので、この点に関しても両方に同じソースコードを置いて機能するというのは無理がありそうに思います。

サーバ機能とクライアント機能を両立させるにはマルチスレッドとキューを利用する方法(こっちがわりと一般的かとおもいます)、ノンブロッキングにする方法があるようです(こっちの方法は私にも良く分かりません)。

参考)
https://blog.amedama.jp/entry/2017/03/29/080000

もしやりたいことが違っているようでしたらごめんなさいですが、ブロッキングの概念、マルチスレッドやキューの処理を学ばれると、お望みのことができるようになるかもしれません。

投稿2021/09/27 12:01

AbeTakashi

総合スコア4853

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

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

FIC-d

2021/09/27 12:29

回ありがとうございました。後でもう一度やってみたのですが、うまくいきました。
AbeTakashi

2021/09/27 12:35

上手くいって良かったです。できれば上手く行った方法を自己回答し、ベストアンサーにされるとなお良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問