Python:在Unix中拒绝Socket.error连接[Errno 111]

Python: Socket.error Connection Refused in Unix [Errno 111]

我正在尝试使用Python中的套接字发送UDP视频包。

服务器IP地址为:192.168.67.14

客户端IP地址为192.168.67.42

客户机和服务器可以彼此ping。下面是用于建立套接字的代码:

服务器端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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)

客户端

1
2
3
4
5
6
7
8
9
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

我花了一些时间研究这个讨论,但我仍然不确定要修改什么。有什么建议吗?


这里有很多问题。首先,通过在服务器端使用connect,您告诉操作系统您将只与IP地址"192.168.67.42"端口5000通信。这可能不是你想要的。(服务器通常与客户机想与之对话的任何对象进行对话。)

第二,通过在客户机中不指定SOCK_DGRAM,您得到的是默认的套接字类型,即SOCK_STREAM。这意味着您的客户机正试图通过TCP端口80(而不是UDP端口80)将cx1(0)发送到您的服务器(这两个名称空间是完全独立的)。

对于一个UDP"会话",双方都需要一个IP地址和一个端口号。如果您没有指定一个端口,操作系统将为您选择一个准随机端口。为了连接客户机和服务器,他们必须至少在其中一个方面达成一致。

所以一个典型的udp服务器将bind连接到一个众所周知的端口(大概您打算使用5000个端口)。然后客户端可以在该端口向服务器发送ecx1〔0〕。代码看起来像这样(无错误处理):

服务器端:

1
2
3
4
5
6
7
8
9
10
11
# 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)

客户机与您拥有的很接近,但是您应该首先将一些数据从客户机发送到服务器,以便服务器知道您的地址:

1
2
3
4
5
6
7
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)

请注意,由于您在客户端使用了connect,因此您已经永久指定了您的对等方地址,不需要使用recvfromsendto


在客户端,这是错误的:

1
s = socket.socket()

要接收UDP数据包,需要创建一个UDP套接字,与在服务器端执行的操作相同:

1
s = socket(AF_INET, SOCK_DGRAM)

此外,如果您希望客户机能够接收UDP数据包,则需要将()绑定到端口5000(connect()既不必要也不足够)。