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

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

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

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

TCP

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

Python

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

Q&A

解決済

2回答

10011閲覧

Pythonを使ってVPS同士でのTCP接続が出来ない

yami_0613

総合スコア22

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

TCP

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

Python

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

0グッド

0クリップ

投稿2016/08/13 02:40

###前提・実現したいこと
Pythonでソケット通信を用いたチャットっぽいプログラムを作成する
###発生している問題・エラーメッセージ

Traceback (most recent call last):
File "client.py", line 6, in <module>
clientsock.connect((host,port))
File "/usr/lib64/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused

###該当のソースコード
サーバー側のソース
import socket

host = "サーバー側VPSのグローバルIPアドレス"
port = 6666

serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind((host,port))
serversock.listen(10)

print 'Waiteing for connections...'
clientsock, client_address = serversock.accept()

while True:
rcvmsg = clientsock.recv(1024)
print 'Received -> %s' % (rcvmsg)
if rcvmsg == '':
break
print 'Type message...'
s_msg = raw_input()
if s_msg == '':
break
print 'wait...'

clientsock.sendall(s_msg)

clientsock.close()

クライアント側のソース
import socket
host = 'クライアント側VPSのグローバルIPアドレス'
port = 6666

clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsock.connect((host,port))

while True:
print 'Type message...'
c_msg = raw_input()
if c_msg == '':
break
print 'Wait...'

clientsock.sendall(c_msg) rcvmsg = clientsock.recv(1024) print 'Received -> %s' % (rcvmsg) if rcvmsg == '': break

clientsock.close()

###試したこと
Pythonの対話形式でクライアント側VPSのソースを一文ずつ打鍵していくとエラーが出ました。

↓打鍵したソースの一文
clientsock.connect((host,port))
↓エラー内容
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused

###補足情報(言語/FW/ツール等のバージョンなど)
OS:CentOS Linux release 7.2.1511 (Core)
Python:Python 2.7.5
サーバー側VPSを実行するとエラーの表示はありませんでした。

###最後に
上記エラーを解決する方法教えて頂けますでしょうか。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

Connection refused というエラーですから、サーバとクライアントですれ違っていることが考えられます。

TCP/IPでは、サーバ側は特定ポートで待ち受け、クライアント側はそのサーバ側ポートにめがけて接続するようにします。質問のソースでは、明らかな問題が一つ、不審な点が一つあります:

  1. クライアント側は、サーバ側ポートをめがけて接続する。つまり、connectに与える引数は、サーバのIPアドレスとポートであるが、質問のソースではサーバではなくクライアントのIPアドレスを指定している。
  2. サーバ側は、どのIPアドレスへの接続を受信するかを限定することができる。bindに与える引数に指定している「サーバー側VPSのグローバルIPアドレス」が、そのサーバに直接アサインされたアドレスであれば問題はないが、ルータでNATしているようなケースだと、サーバにアサインされたアドレスとグローバルIPアドレスが異なる場合があるため、まずは''を指定することで、限定なくbindするべき。

参考: http://docs.python.jp/3/howto/sockets.html#creating-a-socket

s.bind(('', 80)) はこのマシンが持っている全てのアドレスで接続可能になるようにという指定になる。

投稿2016/08/13 03:23

matobaa

総合スコア2493

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

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

yami_0613

2016/08/13 04:05

matobaa様 ご回答ありがとうございます。 ご指摘通り、サーバー側の設定を変えてみました。↓ serversock.bind(('',port)) 併せてクライアント側の設定も変えてみました。↓ host = 'サーバー側のIP' port = 6666 clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) clientsock.connect((host,port)) 再度実行しますと下記のエラー表示されました。 Traceback (most recent call last): File "client1.py", line 6, in <module> clientsock.connect((host,port)) File "/usr/lib64/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 113] No route to host No route to hostと言うのは宛先への経路情報を持っていないという事でしょうか? TCPによる接続が出来ない可能性があるのでしょうか? お手数ですが、ご教授の程よろしくお願いいたします。
yami_0613

2016/08/13 04:31

matobaa様 お蔭さまでTCP接続できました。 ありがとうございました。
guest

0

ベストアンサー

ファイアフォール(iptables等)で通信がブロックされていませんでしょうか?

投稿2016/08/13 03:11

yukkeorg

総合スコア985

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

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

yami_0613

2016/08/13 03:28

回答ありがとうございます。 さっそくiptablesでtcp/6666ポートを許可する設定を入れてみましたが、同様のエラーが出ました。 ちなみに設定したiptablesはこちらです。 iptables -A INPUT -m state --state NEW -p tcp --dport 6666 -j ACCEPT ↑を両VPSで設定しました。 念のためIPアドレスでも許可できるiptables設定を入れました。 結果は変わりませんでした。 よろしくお願いします。
yukkeorg

2016/08/13 03:36

iptablesには何か設定されていましたか? その場合は追加した設定の位置も関係がありますので合わせて確認頂ければと。 (特にRejectしている後ろに追加しても意味が無いので…) また、matobasさんが細かく問題点を回答していますので、そちらも合わせて確認ください。
yami_0613

2016/08/13 03:59

yukkeorg様 iptablesの設定確認致しましたところ 下記のような設定がありました。 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2332 192K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 1 240 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 840 120K INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0 840 120K INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0 840 120K INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0 2 116 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 819 119K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:6666 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6666 0 0 ACCEPT tcp -- * * {相手先のVPSIP} 0.0.0.0/0 tcp dpt:6666 ↑の設定を見るともうすでに全許可の設定があるということでしょうか?
yukkeorg

2016/08/13 04:17

iptablesは基本的にパケットに対してルールのリストを上から確認していき、ルールに一致しているところでそのパケットの処理が行われ、それ以降のルールは確認されません。 今回追加したルールは、追加された分(下3行)の直上にすべてのパケットを破棄するルールがあるため、ここでパケットが捨てられてしまい、追加したルールまで到達しません。従いまして、なんとか、パケットを破棄するルールより前に今回追加したルールを挿入する必要があります。 CentOS7はファイアウォールの管理をfirewalld(中でipatablesを利用している)というプログラムで管理していますので、そのマニュアル等を確認して調節してみてください。
yukkeorg

2016/08/13 04:24 編集

なお、 2332 192K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED については、既に接続が確立されている通信に適用されますので、通信開始時にはこのルールは適用されません。 また、 1 240 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 については、localhost(ループバック)に対する全て通信に対して適用されます。 従いまして、外部の通信に対する全許可はされてい無いかと思います。
yami_0613

2016/08/13 04:29

yukkeorg様 ご指摘通りfirewalldを停止させてところ TCP接続できました!! systemctl stop firewalld ありがとうございます!
yukkeorg

2016/08/13 04:36

おめでとうございます。 なお、インターネットに公開されているサーバの場合ファイアーフォール無効化は非常に危険なので、ファイアウォ―ルにルールを追加する形で作成したアプリが動作するようにしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問