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

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

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

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

Docker

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

Python

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

受付中

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

tekondo
tekondo

総合スコア0

Socket.IO

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

Docker

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

Python

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

0回答

0評価

0クリップ

5閲覧

投稿2019/01/20 12:42

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

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

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

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

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

#やったこと

composeyml

version: '3' services: server: build: . tty: true volumes: - ./:/usr/share/socket working_dir: "/usr/share/socket" client: build: . tty: true volumes: - ./:/usr/share/socket working_dir: "/usr/share/socket"

Dockerfile

FROM python:3.6 ENV LANG C.UTF-8 RUN apt-get update RUN apt-get install vim -y

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

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

を実行して

server.py

python

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

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だと弾かれてしまう理由が知りたいです。
もしご存知の方がいらっしゃいましたら教えていただけると幸いです。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

wwbQzhMkhhgEmhU
wwbQzhMkhhgEmhU

2019/01/20 21:10

コンテナが違うともはや別のネットワークアダプタ\(NIC\)と考えるべきです。 https://qiita\.com/tsukapah/items/54f5c97ab77d3e409732
tekondo
tekondo

2019/01/21 03:54 編集

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

2019/01/21 04:02

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

2019/01/26 08:05

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

2019/01/26 08:12

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

2019/01/26 08:45

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

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Socket.IO

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

Docker

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

Python

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