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

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

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

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

Python

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

Q&A

解決済

1回答

4783閲覧

Pythonでの複数ソケットを使用したTCP通信

whesty

総合スコア16

TCP

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

Python

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

0グッド

0クリップ

投稿2019/11/15 07:50

2つのソケットを使用したTCP通信のプログラムを作成しようとしています。
クライアント側で送りたいメッセージを2つ入力して送り、サーバー側で受け取り、連結されて表示させることを行なっています。
実行することができたのですが、これは2つのソケットを使用して送れていると考えていいのでしょうか?
現在は2つのソケットを使用し、逐次処理でメッセージを送っていますが、目標はスレッドを使用し、同時に2つのメッセージを送るプログラムを作成したいと考えています。どのように変更していけばいいのでしょうか?

よろしくお願いいたします。

###実行結果
client

Python

1Input sentence1:Mac 2Input sentence2:Book 3start Sending 4Done Sending

server

Python

1server is ready to receive 2connected 3Done Receiving 4Received:Mac 5Received:Book 6Received Message:MacBook

該当のソースコード

client

Python

1from socket import* 2 3IP = "****" 4PORT = 9000 5Address = (IP,PORT) 6#ソケットの作成 7clientSocket1 = socket(AF_INET,SOCK_STREAM) 8clientSocket2 = socket(AF_INET,SOCK_STREAM) 9 10#サーバーとの接続 11clientSocket1.connect(Address) 12clientSocket2.connect(Address) 13#データの入力 14sentence1 = input('Input sentence1:') 15sentence2 = input('Input sentence2:') 16print ("start Sending") 17#送信 18clientSocket1.send(sentence1.encode()) 19clientSocket2.send(sentence2.encode()) 20print ("Done Sending") 21 22#ソケットを閉じる 23clientSocket1.close() 24clientSocket2.close() 25

server
breakで無理やりループを抜けてます。

Python

1from socket import* 2 3PORT = 9000 4#ソケットの作成 5serverSocket = socket(AF_INET,SOCK_STREAM) 6#アドレスの設定 7serverSocket.bind(("****",PORT)) 8 9 10#接続の待ち受け 11serverSocket.listen(1) 12 13#メッセージ表示 14print ('server is ready to receive') 15 16while True: 17 #ソケットの修得 18 connectionSocket1, addr = serverSocket.accept() 19 connectionSocket2, addr = serverSocket.accept() 20 print('connected') 21 sentence1 = connectionSocket1.recv(4096).decode() 22 sentence2 = connectionSocket2.recv(4096).decode() 23 connectionSocket1.close() 24 connectionSocket2.close() 25 break 26 27print ("Done Receiving") 28print("Received:%s"%sentence1) 29print("Received:%s"%sentence2) 30sentence1 += sentence2 31print("Received Message:%s"%sentence1)

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

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

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

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

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

guest

回答1

0

ベストアンサー

実行することができたのですが、これは2つのソケットを使用して送れていると考えていいのでしょうか?

ソケットを2つ作ってデータが混ざることなく送受信しているのですから、「送れている」と考えて良いです。TCPの場合、ソケット1つに対して相手も1つですので。

現在は2つのソケットを使用し、逐次処理でメッセージを送っていますが、目標はスレッドを使用し、同時に2つのメッセージを送るプログラムを作成したいと考えています。どのように変更していけばいいのでしょうか?

一般的にはサーバーは以下のような動きをさせます。多くのサンプルプログラムでもこのようなかたちを成します。ただ、絶対にこのようなかたちでなければならない訳ではありません。サブスレッドを起動させなくても、selectを駆使すればメインスレッドだけでもいけるケースもあります。

0. (初期化処理は割愛します) 1. 何らかの終了条件が満たされるまでループ 1-1. acceptでクライアントからの接続を待ち受け(ここでブロックしている) # acceptから抜けてきたら、クライアントが接続してきた、と言うこと 1-2. acceptで返されたソケットをもって、サブスレッド起動。 以降このソケットについてはこのサブスレッド内で送受信を行う 1-3. ループの先頭へ戻る。(速やかにacceptを実行する) 2. 全サブスレッドの送受信が終わるまで待機。あるいは強制的に終わらせる。 3. メインスレッド終了

今、ご提示のサーバープログラムのコードをどのように直したらよいか?と聞かれたら、大改造になるでしょう。まずは上で示したような流れになるよう、コードを組んでみてください。スレッドの使い方に不安があるのであれば、それを先に習得する必要があると思います。

投稿2019/11/15 18:41

dodox86

総合スコア9183

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

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

whesty

2019/11/17 14:56

回答ありがとうございます! クライアントのほうもスレッドを使用する必要はありますか?
dodox86

2019/11/17 17:04 編集

スレッドを使用すべきかどうかはプログラムの内容とプログラマー次第です。クライアント1つで複数のソケット(コネクション)を使う場合、ひとつひとつに時間がかからなければスレッドを使うまでも無いと思いますが、1つのソケットで1つのスレッドにすると、そのスレッドはそのソケットの処理に専念できる、というメリットもあります。別のケースでもしGUIを持つクライアントだった場合、ソケットを使う処理を別スレッドにしないとGUI部分が固まったようになるので、そんな場合は別スレッドにする必要があるでしょう。クライアントでは1つのソケットしか扱わない作りにして、複数立ち上げて使うようなものも考えられます。 質問中で「目標はスレッドを使用し、同時に2つのメッセージを送るプログラムを作成したい」とありますが、まだこれでは漠然とした仕様のように思いますので、細かく最終的にどうしたいか、発展の仕方によるかな、と思います。
whesty

2019/11/18 08:15

最終目標はクライアント1つで複数のソケットを使用し、1つのファイル(データ)をサーバーに送る(並列コネクション)プログラムを作成することです。 1つのソケットで1つのスレッドにしたいと思ってます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問