2016-12-23 88 views
0

Pythonでソケットを使用してUDPビデオパケットを送信しようとしています。Python:UnixでSocket.error接続が拒否されました[Errno 111]

サーバのIPアドレスは次のとおりです。192.168.67.14

クライアントのIPアドレスは、クライアントとサーバが互いをpingできる192.168.67.42

です。以下は、ソケットを確立するために使用されるコードは次のとおりです。

サーバー側:私は取得

import urllib, time, os, m3u8 
from socket import * 

# Socket initialization 

s = socket(AF_INET, SOCK_DGRAM) 
host = "192.168.67.42" 
port = 5000 
buf = 1024 
addr = (host, port) 
s.connect((host, port)) 

ts_filenames = [] 
while True: 
    playlist = "https://sevenwestmedia01-i.akamaihd.net/hls/live/224853/TEST1/master_lowl.m3u8" 
    m3u8_obj = m3u8.load(playlist) 
    ts_segments = m3u8_obj.__dict__.values()[6] 
    ts_segments_str = str(m3u8_obj.segments) 
    for line in ts_segments_str.splitlines(): 
     if "https://" in line: 
      ts_id = line[-20:] 
      if ts_id not in ts_filenames: 
       print ts_id 
       ts_filenames.append(ts_id) 
       try: 
        ts_segment = urllib.URLopener() 
        ts_segment.retrieve(line, ts_id) 
       except: 
        pass 
       f = open(ts_id, "rb") 
       data = f.read(buf) 
       while (data): 
        if (s.sendto(data, addr)): 
         print "sending ..." 
         data = f.read(buf) 

クライアント側

import socket 

s = socket.socket() 
host = '192.168.67.14' 
port = 5000 

s.connect((host,port)) 
print s.recv(1024) 
s.close 

例外:

Traceback (most recent call last): File "client.py", line 7, in s.connect((host,port)) File "/usr/lib/python2.7/socket.py", line 228, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 111] Connection refused

私はに探していくつかの時間を費やしthis discussionしかし、私はまだ何を修正するか分からない。何か提案してください?クライアント側では、これは間違っている

答えて

2

ここには複数の問題があります。最初に、サーバ側でconnectを使用すると、IPアドレス "192.168.67.42"ポート5000としか通信しないことがオペレーティングシステムに伝えられます。これはおそらく意図したとおりではありません。

クライアントでSOCK_DGRAMを指定しないと、デフォルトのソケットタイプ(SOCK_STREAM)が得られます。これは、クライアントがのTCPポート80で、サーバにconnectを送信しようとしていることを意味します。UDPポート80ではなく2つの名前空間は全く別です。

UDP「セッション」の場合、両側にIPアドレスとポート番号が必要です。特にポートをbindに設定しないと、オペレーティングシステムが準ランダムに選択します。クライアントとサーバーをリンクさせるには、少なくとも1つは同意する必要があります。

したがって、一般的なUDPサーバーは、よく知られているポートにbind(おそらくその目的で5000を指定したものとします)になります。その後、クライアントはそのポートのサーバーにconnectを送信できます。

サーバー側:

# Create socket 
s = socket(AF_INET, SOCK_DGRAM) 
# Bind to our well known port (leave address unspecified 
# allowing us to receive on any local network address) 
s.bind(('', 5000)) 

# Receive from client (so we know the client's address/port) 
buffer, client_addr = s.recvfrom(1024) 

# Now we can send to the client 
s.sendto(some_buffer, client_addr) 

クライアントはあなたが持っているものに近いですが、クライアントからサーバにいくつかのデータを送信しなければならないコードは、この(サンセリフエラー処理)のようになります。あなたは、クライアント側でconnectを使用しているので、あなたは永久にあなたのピアのアドレスを指定したとを使用する必要がないこと

s = socket(AF_INET, SOCK_DGRAM) 
# Create connection to server (the OS will automatically 
# bind a port for the client) 
s.connect((host, port)) 
# Send dummy data to server so it knows our address/port 
s.send(b'foo') 
buffer = s.recv(1024) 

注:最初のサーバーは、あなたのアドレスを知っているので、 0およびsendto

+0

提案をいただきありがとうございます:接続エラーはなくなり、クライアントインターフェイスでトラフィックをキャプチャできます...しかし、クライアントが実際にトラフィックを受信して​​いることをどのように確認できますか?クライアントには印刷s.recv(1024)がありますが、端末に何も表示されません –

+0

サーバのデータグラムがクライアントに届かないような音がしますか?クライアントの*接続*の後に、 's.getsockname()'の値を表示します。サーバでは、 'recvfrom'が終了した後、' client_addr'の値を出力します。それらは一致する必要があります。もしそうであれば、 'sendto'はそのアドレスのクライアントにデータを送り返すことができます。まだ動作していない場合は、何を助言するべきかわからない:tcpdumpやwiresharkを使って、 "ワイヤ上の"パケットがどんなものか見てみよう。 –

2

s = socket.socket() 

UDPパケットを受信するため、あなたは、サーバー側でやったのと同じUDPソケットを作成する必要があります。

s = socket(AF_INET, SOCK_DGRAM) 

もクライアントがUDPパケットを受信できるようにするには、ポート5000にbind()する必要があります(connect()はそれに必要でも十分でもありません)。

+0

ありがとうございました: クライアントをs = socket(AF_INET、SOCK_DGRAM)に変更しましたが、今では例外が発生しません...サーバーが次の例外を与えています:トレースバック(最新最後の呼び出し): ファイル "decryptvideo.py"、行43、 if(s.sendto(data、addr)): socket.error:[Errno 111] Connection refused –

+0

興味深いのは、クライアントが今すぐポート5000で聞く netstat | grep 5000 udp 0 0 192.168.67.42:59249 192.168.67.14:5000 ESTABLISHED –

+0

ポート上でパケットを受信するためにbind()を呼び出す必要性についての最後の段落に留意してください。 –

関連する問題