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

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

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

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

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Python

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

Q&A

0回答

2039閲覧

docker内でlocalhostへのsocket通信ができない

tekondo

総合スコア26

Socket.IO

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

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Python

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

0グッド

0クリップ

投稿2019/01/20 12:42

今Socketモジュールを使用してDockerコンテナ同士でSocket通信をしようと思っています。

クライアントコンテナ、サーバーコンテナを作成してそれぞれをSocketで繋ごうとしています。

Docker-composeで二つのコンテナをリンクさせ、IPアドレスを名前解決で指定しようとしているのですが

エラーが出てしまいます。

ですので一度localhostを経由してコネクションを確立させようと思い以下のプログラムを作成しました。

#やったこと

composeyml

1version: '3' 2services: 3 server: 4 build: . 5 tty: true 6 volumes: 7 - ./:/usr/share/socket 8 working_dir: "/usr/share/socket" 9 10 client: 11 build: . 12 tty: true 13 volumes: 14 - ./:/usr/share/socket 15 working_dir: "/usr/share/socket" 16

Dockerfile

1FROM python:3.6 2ENV LANG C.UTF-8 3 4RUN apt-get update 5RUN apt-get install vim -y

こちらでコンテナを二つ起動して

docker-compose -f $(COMPOSE_FILE) -p $(PROJECT) up -d --build

を実行して

server.py

python

1import socket 2import os 3import subprocess 4 5def main(): 6 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 # client_ip = str(subprocess.call(['dig', 'client', '+short'])) 8 # UNIXコマンド打ち込んでclientのIPを取得 9 # s.bind((client_ip, 50007)) # 指定したホスト(IP)とポートをソケットに設定 10 s.bind(("localhost", 50006)) # 指定したホスト(IP)とポートをソケットに設定 11 s.listen(1) # 1つの接続要求を待つ 12 soc, addr = s.accept() # 要求が来るまでブロック 13 print("Conneted by"+str(addr)) #サーバ側の合図 14 15 while (1): 16 print("Server>") 17 data = input().encode('utf-8') # 入力待機(サーバー側) 18 soc.send(data) # ソケットにデータを送信 19 data = soc.recv(1024) # データを受信(1024バイトまで) 20 data = data.decode('utf-8') 21 print("Client>",data) # サーバー側の書き込みを表示 22 if data == "q": # qが押されたら終了 23 soc.close() 24 break 25 26main() 27 28

client.py

import socket def main(): # host = socket.gethostname() # # 自身のIPアドレスを取得 # ip = socket.gethostbyname(host) soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 取得したIPアドレスを元に接続 # soc.connect((ip, 50007)) soc.connect(("localhost", 50006)) # 指定したホスト(IP)とポートをソケットに設定 while(1): data = soc.recv(1024) data = data.decode('utf-8') print("Server>", data) # サーバー側の書き込みを表示 print("Client>") data = input().encode('utf-8') # 入力待機 soc.send(data) # ソケットに入力したデータを送信 data = data.decode('utf-8') # 入力待機 if data == "q": # qが押されたら終了 soc.close() break main()

を実行したところ

server.pyは実行できてクライアントの接続を待つのですが、
client.pyを実行すると

Traceback (most recent call last): File "client.py", line 24, in <module> main() File "client.py", line 10, in main soc.connect(("localhost", 50006)) # 指定したホスト(IP)とポートをソケットに設定 ConnectionRefusedError: [Errno 111] Connection refused

とエラーメッセージが出てしまいます。

確認したところ

docker コンテナ内でなくローカル上で上記のプログラムが動作することは確認しています。
dockerだと弾かれてしまう理由が知りたいです。
もしご存知の方がいらっしゃいましたら教えていただけると幸いです。

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

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

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

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

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

tekondo

2019/01/21 03:54 編集

ご回答ありがとうございます。 貼っていただいたリンクを参照したところ、 >Bridgeネットワーク内の通信なので、それぞれホスト側で公開したport(8080や8090)ではなく、 元々コンテナ自身がListenしているポート(80)でアクセスできていることにも注目してもらえると良いと思います。 とのことなので、今回のclientとserverは通信できる気がするのですが、いかがでしょうか? compose.ymlでリンクさせているので二つのコンテナはsocket_defaultネットワークで繋がっています。 もし私の認識不足である場合はそちら言って頂けると幸いです。
wwbQzhMkhhgEmhU

2019/01/21 04:02

とりあえずよく読んでませんでした。すみません。リンクを意図してたんですね。 ただ、コンテナが違えば基本はPCが違うようなものなので、clientからserverに繋ぎに行くときはlocalhost指定だと駄目な気がします。 soc.connect(("server", 50006)) だとどうでしょう?
tekondo

2019/01/26 08:05

いけました!!!! ありがとうございます。 ちなみになのですが、 soc.connect(("client", 50006)) では接続できませんでした。 この理由って何かご存知でしょうか??
wwbQzhMkhhgEmhU

2019/01/26 08:12

単に名前解決できるようにしてるだけだと思うので、必要ないと思ったのかも。よく分かりません。 ちなみに3くらいからリンクは非推奨だった気がします。忘れましたが。
tekondo

2019/01/26 08:45

そうなんですね、自分の方で調べてみます。 明示的なLinkは非推奨になりましたがComposeによるNetworkは別だったはずです。 解決できましたありがとうございます!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問