我正在尝试使用Python中的套接字发送UDP视频数据包。
服务器IP地址为:192.168.67.14
客户端IP地址为192.168.67.42
客户端和服务器可以互相ping通。下面是用于建立套接字的代码:
服务器端:
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(最近一次调用最后一次):文件“client.py”,第7行,in s.connect((host,port))文件“/usr/lib/python2.7/socket.py”,第228行,在meth return getattr(self._sock,name)(* args)socket.error:[Errno 111]连接被拒绝
我花了一些时间研究this discussion,但我仍然不确定要修改什么。有什么建议吗?
答案 0 :(得分:3)
这里有多个问题。首先,通过在服务器端使用connect
,您告诉操作系统您将只与IP地址进行通信" 192.168.67.42"端口5000.这可能不是你想要的。 (服务器通常会与任何客户想与之交谈。)
其次,如果未在客户端中指定SOCK_DGRAM
,则会获得默认套接字类型SOCK_STREAM
。这意味着您的客户端正在尝试connect
到 TCP 端口80上的服务器 - 而不是UDP端口80(两个名称空间完全独立)。
对于UDP"会话",双方都需要IP地址和端口号。如果您没有专门bind
个端口,操作系统将为您准备一个随机的端口。为了连接客户端和服务器,他们必须至少同意其中一个。
因此,典型的UDP服务器将bind
发送到一个众所周知的端口(大概是为了这个目的而建议你使用5000)。然后客户端可以connect
到该端口的服务器。代码看起来像这样( sans 错误处理):
服务器端:
# 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)
客户端已接近您所拥有的,但您应首先将一些数据从客户端发送到服务器,以便服务器知道您的地址:
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
,因此您已永久指定了同行的地址,并且不需要使用recvfrom
和{{ 1}}。
答案 1 :(得分:2)
在客户端,这是错误的:
s = socket.socket()
要接收UDP数据包,您需要创建一个UDP套接字,与服务器端相同:
s = socket(AF_INET, SOCK_DGRAM)
此外,如果您希望您的客户端能够接收UDP数据包,您需要将其绑定()到端口5000(connect()既不必要也不足够)。