importsocketimporthashlibimportbase64importtime

config_dict={'server_username': 'admin', #RTSP用户名

'server_password': '123456', #RTSP用户名对应密码

'server_ip': '10.10.6.92', #RTSP服务器IP地址

'server_port': 554, #RTSP服务器使用端口

'server_path': '/chIP=1&streamType=main/', #URL中端口之后的部份,测试发现不同服务器对这部份接受的值是不一样的,也就是说自己使用时很可能得自己修改这部份的值

'cseq': 2, #RTSP使用的请求起始序列码,不需要改动

'user_agent': 'LibVLC/3.0.2 (LIVE555 Streaming Media v2016.11.28)', #自定义请求头部

'buffer_len': 1024, #用于接收服务器返回数据的缓冲区的大小

'auth_method': 'Digest', #RTSP使用的认证方法,Basic/Digest

'header_normal_modify_allow': False, #是否允许拼接其他协议规定的请求头的总开关,请些请求头的值为正常值(大多是RFC给出的示例)

'header_overload_modify_allow': False, #是否允许拼接其他协议规定的请求头的总开关,请些请求头的值为超长字符串

'options_header_modify': True, #OPTIONS请求中,是否允许拼接其他协议规定的请求头的开关

'describe_header_modify': True, #第一次DESCRIBE请求中,是否允许拼接其他协议规定的请求头的开关

'describe_auth_header_modify': True, #第二次DESCRIBE请求中,是否允许拼接其他协议规定的请求头的开关

'setup_header_modify': True, #第一次SETUP请求中,是否允许拼接其他协议规定的请求头的开关

'setup_session_header_modify': True, #第二次SETUP请求中,是否允许拼接其他协议规定的请求头的开关

'play_header_modify': True, #PLAY请求中,是否允许拼接其他协议规定的请求头的开关

'get_parameter_header_modify': True, #GET PARAMETER请求中,是否允许拼接其他协议规定的请求头的开关

'teardown_header_modify': True #TEARDOWN请求中,是否允许拼接其他协议规定的请求头的开关

}classRtspClient():def __init__(self):#self.socket_send = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#self.socket_send.settimeout(5)

#self.socket_send.connect((config_dict['server_ip'], config_dict['server_port']))

pass

#用于Digest认证方式时生成response的值

defgen_response_value(self,url,public_method,realm,nonce):

frist_pre_md5_value= hashlib.md5((config_dict['server_username'] + ':' + realm + ':' + config_dict['server_password']).encode()).hexdigest()

first_post_md5_value= hashlib.md5((public_method+':' +url).encode()).hexdigest()

response_value= hashlib.md5((frist_pre_md5_value + ':' + nonce + ':' +first_post_md5_value).encode()).hexdigest()returnresponse_value#生成options请求头部

defgen_options_header(self):globalconfig_dict

str_options_header= 'OPTIONS rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) +config_dict['server_path'] + 'RTSP/1.0\r\n'str_options_header+= 'CSeq:' + str(config_dict['cseq']) + '\r\n'str_options_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_options_header+= '\r\n'

returnstr_options_header#生成第一次describe请求头部

defgen_describe_header(self):globalconfig_dict

str_describe_header= 'DESCRIBE rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) +config_dict['server_path'] + 'RTSP/1.0\r\n'str_describe_header+= 'CSeq:' + str(config_dict['cseq'] + 1) + '\r\n'str_describe_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_describe_header+= 'Accept: application/sdp\r\n'str_describe_header+= '\r\n'

returnstr_describe_header#生成第二次describe请求头部

defgen_describe_auth_header(self,url,realm,nonce):globalconfig_dict

public_method= 'DESCRIBE'str_describe_auth_header= 'DESCRIBE rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) + config_dict['server_path'] + 'RTSP/1.0\r\n'str_describe_auth_header+= 'CSeq:' + str(config_dict['cseq'] + 2) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_describe_auth_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_describe_auth_header+= 'Authorization: Digest username="'+config_dict['server_username']+'", realm="'+realm+'", nonce="'+nonce+'", uri="'+url+'", response="'+response_value+'"\r\n'str_describe_auth_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_describe_auth_header+= 'Accept: application/sdp\r\n'str_describe_auth_header+= '\r\n'

returnstr_describe_auth_header#生成第一次setup请求头部

defgen_setup_header(self,url, realm, nonce):globalconfig_dict

public_method= 'SETUP'str_setup_header= 'SETUP rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) + config_dict['server_path'] + 'trackID=0 RTSP/1.0\r\n'str_setup_header+= 'CSeq:' + str(config_dict['cseq'] + 3) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_setup_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_setup_header+= 'Authorization: Digest username="'+config_dict['server_username']+'", realm="'+realm+'", nonce="'+nonce+'", uri="'+url+'", response="'+response_value+'"\r\n'str_setup_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_setup_header+= 'Transport: RTP/AVP;unicast;client_port=50166-50167\r\n'str_setup_header+= '\r\n'

returnstr_setup_header#生成第二次setup请求头部

defgen_setup_session_header(self,url, realm, nonce,session):globalconfig_dict

public_method= 'SETUP'str_setup_session_header= 'SETUP rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) +config_dict['server_path'] + 'trackID=1 RTSP/1.0\r\n'str_setup_session_header+= 'CSeq:' + str(config_dict['cseq'] + 4) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_setup_session_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_setup_session_header+= 'Authorization: Digest username="'+config_dict['server_username']+'", realm="'+realm+'", nonce="'+nonce+'", uri="'+url+'", response="'+response_value+'"\r\n'str_setup_session_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_setup_session_header+= 'Transport: RTP/AVP;unicast;client_port=50168-50169\r\n'str_setup_session_header+= 'Session:'+session+'\r\n'str_setup_session_header+= '\r\n'

returnstr_setup_session_header#生成play请求头部

defgen_play_header(self,url, realm, nonce,session):globalconfig_dict

public_method= 'PLAY'str_play_header= 'PLAY rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) +config_dict['server_path'] + 'RTSP/1.0\r\n'str_play_header+= 'CSeq:' + str(config_dict['cseq'] + 5) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_play_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_play_header+= 'Authorization: Digest username="'+config_dict['server_username']+'", realm="'+realm+'", nonce="'+nonce+'", uri="'+url+'", response="'+response_value+'"\r\n'str_play_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_play_header+= 'Session:'+session+'\r\n'str_play_header+= 'Range: npt=0.000-\r\n'str_play_header+= '\r\n'

returnstr_play_header#生成GET_PARAMETER请求头部

defgen_get_parameter_header(self,url, realm, nonce, session,count):globalconfig_dict

public_method= 'GET_PARAMETER'str_get_parameter_header= 'GET_PARAMETER rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) +config_dict['server_path'] + 'RTSP/1.0\r\n'str_get_parameter_header+= 'CSeq:' + str(config_dict['cseq'] + 6+int(count)) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_get_parameter_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_get_parameter_header+= 'Authorization: Digest username="' +config_dict['server_username'] + '", realm="' + realm + '", nonce="' + nonce + '", uri="' + url + '", response="' + response_value + '"\r\n'str_get_parameter_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_get_parameter_header+= 'Session:' + session + '\r\n'str_get_parameter_header+= '\r\n'

returnstr_get_parameter_header#生成teardown请求头部

defgen_teardown_header(self,url, realm, nonce, session):globalconfig_dict

public_method= 'TEARDOWN'str_teardown_header= 'TEARDOWN rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) + config_dict['server_path'] + 'RTSP/1.0\r\n'str_teardown_header+= 'CSeq:' + str(config_dict['cseq'] + 11) + '\r\n'

if config_dict['auth_method'] == 'Basic':

auth_64= base64.b64encode((config_dict['server_username'] + ":" + config_dict['server_password']).encode("utf-8")).decode()

str_teardown_header+= 'Authorization: Basic'+auth_64 + '\r\n'

else:

response_value=self.gen_response_value(url, public_method, realm, nonce)

str_teardown_header+= 'Authorization: Digest username="' +config_dict['server_username'] + '", realm="' + realm + '", nonce="' + nonce + '", uri="' + url + '", response="' + response_value + '"\r\n'str_teardown_header+= 'User-Agent:' + config_dict['user_agent'] + '\r\n'str_teardown_header+= 'Session:' + session + '\r\n'str_teardown_header+= '\r\n'

returnstr_teardown_header#拼接rtsp协议的其他请求头,以测试程序对这些请求头部的处理是否有问题;这个方法与add_overload_header_according_to_protocol是互斥的

defadd_normal_header_according_to_protocol(self,str_header):

str_header= str_header[0:len(str_header)-2]

str_header+= 'Accept: application/rtsl, application/sdp;level=-2'str_header+= 'Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0\r\n'str_header+= 'Accept-Language: da, en-gb;q=0.8, en;q=0.7\r\n'str_header+= 'Bandwidth: 4000 \r\n'str_header+= 'Blocksize: 4000 \r\n'str_header+= 'Cache-Control: no-cache;max-stale \r\n'str_header+= 'Conference: 199702170042.SAA08642@obiwan.arl.wustl.edu%20Starr \r\n'str_header+= 'Connection: close\r\n'str_header+= 'Content-Base: gzip\r\n'str_header+= 'Content-Encoding: gzip\r\n'str_header+= 'Content-Language: mi,en\r\n'str_header+= 'Content-Length: 2034953454546565 \r\n'str_header+= 'Content-Location: /etc/passwd\r\n'str_header+= 'Content-Type: text/html; charset=ISO-8859-4gg\r\n'str_header+= 'Date: Tue, 15 Nov 1995x 08:12:31 GMT\r\n'str_header+= 'Expires: Thu, 01 Dec 1994 16:00:00 GMT \r\n'str_header+= 'From: webmaster@w3.org\r\n'str_header+= 'If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT \r\n'str_header+= 'Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT\r\n'str_header+= 'Proxy-Require: funky-feature\r\n'str_header+= 'Referer: http://www.w3.org/hypertext/DataSources/Overview.html\r\n'str_header+= 'Require: funky-feature \r\n'str_header+= 'Scale: -3.5 \r\n'str_header+= 'Speed: 2.5 \r\n'str_header+= 'Transport: RTP/AVP;unicast;client_port=3456-3457;mode="PLAY" \r\n'str_header+= 'Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)\r\n'str_header+= 'Range: npt=2\r\n'str_header+= '\r\n'

returnstr_header#拼接rtsp协议的其他请求头,并将这些请求头的字赋为超长字符串,以测试程序对这些请求头部的处理是否有缓冲区溢出问题;这个方法与add_normal_header_according_to_protocol是互斥的

defadd_overload_header_according_to_protocol(self,str_header):

str_header= str_header[0:len(str_header) - 2]

str_header+= 'Accept: application/rtsl012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789, application/sdp;level=-2012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'str_header+= 'Accept-Encoding: gzip01234567890123456789012345678901234567890123456789;q=1.0012345678901234567890123456789012345678901234567890123456789, identity; q=0.5012345678901234567890123456789, *;q=0012345678901234567890123456789\r\n'str_header+= 'Accept-Language: da, en-gb;q=0.80123456789012345678901234567890123456789, en;q=0.7012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n'str_header+= 'Bandwidth: 400001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \r\n'str_header+= 'Blocksize: 4000012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \r\n'str_header+= 'Cache-Control: no-cache;max-stale \r\n'str_header+= 'Conference: 199702170042.SAA08642@obiwan.arl.wustl.edu%20Starr01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \r\n'str_header+= 'Connection: 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789close\r\n'str_header+= 'Content-Base: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789gzip\r\n'str_header+= 'Content-Encoding: 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789gzip\r\n'str_header+= 'Content-Language: 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789mi,en\r\n'str_header+= 'Content-Length: 203495345454656501234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \r\n'str_header+= 'Content-Location: /etc/passwd01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n'str_header+= 'Content-Type: text/html012345678901234567890123456789012345678901234567890123456789; charset=012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789ISO-8859-4gg\r\n'str_header+= 'Date: Tue, 15 Nov 1995x 08:12:310123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 GMT\r\n'str_header+= 'Expires: Thu, 01 Dec 1994 16012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:00:00 GMT \r\n'str_header+= 'From: webmaster@w30123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.org\r\n'str_header+= 'If-Modified-Since: Sat, 29 Oct 1994 19:43:31012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 GMT \r\n'str_header+= 'Last-Modified: Tue, 15 Nov 1994 120123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:45:26 GMT\r\n'str_header+= 'Proxy-Require: funky-feature\r\n'str_header+= 'Referer: http://www.w3.org/hypertext/DataSources/Overview.html\r\n'str_header+= 'Require: funky-feature0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \r\n'str_header+= 'Scale: -0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567893.5 \r\n'str_header+= 'Speed: 20123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.5 \r\n'str_header+= 'Transport: RTP/AVP;unicast;client_port=3456-345012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567897;mode="01234567890123456789PLAY" \r\n'str_header+= 'Via: 1.0 fred, 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891.1 nowhere.com (Apache/0123456789012345678901234567891.1)\r\n'str_header+= 'Range: npt=20123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\r\n'str_header+= '\r\n'

returnstr_header#执行一次完整的rtsp播放请求,OPTIONS/DESCRIBE/SETUP/PLAY/GET PARAMETER/TEARDOWN,如果某个请求不正确则中止

#此方法推荐用于则试服务端是否正确实现RTSP服务

defexec_full_request(self):

self.socket_send=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.socket_send.settimeout(5)

self.socket_send.connect((config_dict['server_ip'], config_dict['server_port']))

url= 'rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) + config_dict['server_path']print('now start to check options operation')

str_options_header=self.gen_options_header()if config_dict['header_normal_modify_allow'] & config_dict['options_header_modify']:

str_options_header=self.add_normal_header_according_to_protocol(str_options_header)elif config_dict['header_overload_modify_allow'] & config_dict['options_header_modify']:

str_options_header=self.add_overload__header_according_to_protocol(str_options_header)

self.socket_send.send(str_options_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if '200 OK' inmsg_recv:print('OPTIONS request is OK')else:print('OPTIONS request is BAD')

str_describe_header=self.gen_describe_header()if config_dict['header_normal_modify_allow'] & config_dict['describe_header_modify']:

str_describe_header=self.add_normal_header_according_to_protocol(str_describe_header)elif config_dict['header_overload_modify_allow'] & config_dict['describe_header_modify']:

str_describe_header=self.add_overload__header_according_to_protocol(str_describe_header)

self.socket_send.send(str_describe_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if msg_recv.find('401 Unauthorized') == -1 &False:

msg_recv_dict= msg_recv.split('\r\n')print('first DESCRIBE request occur error:')print(msg_recv_dict[0])else:print('first DESCRIBE is ok,now we will execute second DESCRIBE for auth')

realm_pos= msg_recv.find('realm')

realm_value_begin_pos= msg_recv.find('"', realm_pos)+1realm_value_end_pos= msg_recv.find('"', realm_pos + 8)

realm_value=msg_recv[realm_value_begin_pos:realm_value_end_pos]

nonce_pos= msg_recv.find('nonce')

nonce_value_begin_pos= msg_recv.find('"', nonce_pos)+1nonce_value_end_pos= msg_recv.find('"', nonce_pos + 8)

nonce_value=msg_recv[nonce_value_begin_pos:nonce_value_end_pos]

str_describe_auth_header=self.gen_describe_auth_header(url, realm_value, nonce_value)if config_dict['header_normal_modify_allow'] & config_dict['describe_auth_header_modify']:

str_describe_auth_header=self.add_normal_header_according_to_protocol(str_describe_auth_header)elif config_dict['header_overload_modify_allow'] & config_dict['describe_auth_header_modify']:

str_describe_auth_header=self.add_overload__header_according_to_protocol(str_describe_auth_header)

self.socket_send.send(str_describe_auth_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if msg_recv.find('200 OK') == -1:

msg_recv_dict= msg_recv.split('\r\n')print('second DESCRIBE request occur error:')print(msg_recv_dict[0])else:print('second DESCRIBE is ok,now we will execute first SETUP for session')

str_setup_header=self.gen_setup_header(url, realm_value, nonce_value)if config_dict['header_normal_modify_allow'] & config_dict['setup_header_modify']:

str_setup_header=self.add_normal_header_according_to_protocol(str_setup_header)elif config_dict['header_overload_modify_allow'] & config_dict['setup_header_modify']:

str_setup_header=self.add_overload__header_according_to_protocol(str_setup_header)

self.socket_send.send(str_setup_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if msg_recv.find('200 OK') == -1:

msg_recv_dict= msg_recv.split('\r\n')print('first SETUP request occur error:')print(msg_recv_dict[0])else:print('first SETUP is ok,now we will execute second SETUP')

session_pos= msg_recv.find('Session')

session_value_begin_pos= msg_recv.find(' ',session_pos+8)+1session_value_end_pos= msg_recv.find(';',session_pos+8)

session_value=msg_recv[session_value_begin_pos:session_value_end_pos]

str_setup_session_header=self.gen_setup_session_header(url, realm_value, nonce_value,session_value)if config_dict['header_normal_modify_allow'] & config_dict['setup_session_header_modify']:

str_setup_session_header=self.add_normal_header_according_to_protocol(str_setup_session_header)elif config_dict['header_overload_modify_allow'] & config_dict['setup_session_header_modify']:

str_setup_session_header=self.add_overload_header_according_to_protocol(str_setup_session_header)

self.socket_send.send(str_setup_session_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if msg_recv.find('200 OK') == -1:

msg_recv_dict= msg_recv.split('\r\n')print('second SETUP request occur error:')print(msg_recv_dict[0])else:print('second SETUP is ok, now we wil execute PLAY')

str_play_header=self.gen_play_header(url, realm_value, nonce_value, session_value)if config_dict['header_normal_modify_allow'] & config_dict['play_header_modify']:

str_play_header=self.add_normal_header_according_to_protocol(str_play_header)elif config_dict['header_overload_modify_allow'] & config_dict['play_header_modify']:

str_play_header=self.add_overload_header_according_to_protocol(str_play_header)

self.socket_send.send(str_play_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()if msg_recv.find('200 OK') == -1:

msg_recv_dict= msg_recv.split('\r\n')print('PLAY request occur error:')print(msg_recv_dict[0])else:print('PLAY is ok, we will execute GET_PARAMETER every 10 seconds and 5 times total')for i in range(2):

str_get_parameter_header=self.gen_get_parameter_header(url, realm_value, nonce_value, session_value,str(i))if config_dict['header_normal_modify_allow'] & config_dict['get_parameter_header_modify']:

str_get_parameter_header=self.add_normal_header_according_to_protocol(str_get_parameter_header)elif config_dict['header_overload_modify_allow'] & config_dict['get_parameter_header_modify']:

str_get_parameter_header=self.add_overload_header_according_to_protocol(str_get_parameter_header)

self.socket_send.send(str_get_parameter_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print(str(i)+'*10:'+msg_recv_dict[0])

time.sleep(10)print('\nnow we will execute TEARDOWN to disconnect with server')

str_teardown_header=self.gen_teardown_header(url, realm_value, nonce_value, session_value)if config_dict['header_normal_modify_allow'] & config_dict['teardown_header_modify']:

str_teardown_header=self.add_normal_header_according_to_protocol(str_teardown_header)elif config_dict['header_overload_modify_allow'] & config_dict['teardown_header_modify']:

str_teardown_header=self.add_overload_header_according_to_protocol(str_teardown_header)

self.socket_send.send(str_teardown_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()print(msg_recv)print('program execute finished, thank you')

self.socket_send.close()#强制依次执行OPTIONS/DESCRIBE/SETUP/PLAY/GET PARAMETER/TEARDOWN,某个请求报错也进行下一个请求

#此方法推荐用于测试服务端是否有溢出漏洞

defexec_force_request(self):

self.socket_send=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.socket_send.settimeout(5)

self.socket_send.connect((config_dict['server_ip'], config_dict['server_port']))

url= 'rtsp://' + config_dict['server_ip'] + ':' + str(config_dict['server_port']) + config_dict['server_path']print('now start to check options operation')

str_options_header=self.gen_options_header()if config_dict['header_normal_modify_allow'] & config_dict['options_header_modify']:

str_options_header=self.add_normal_header_according_to_protocol(str_options_header)elif config_dict['header_overload_modify_allow'] & config_dict['options_header_modify']:

str_options_header=self.add_overload_header_according_to_protocol(str_options_header)

self.socket_send.send(str_options_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the OPTIONS response is :')print(msg_recv_dict[0])print('\nnow we will execute first DESCRIBE request')

str_describe_header=self.gen_describe_header()if config_dict['header_normal_modify_allow'] & config_dict['describe_header_modify']:

str_describe_header=self.add_normal_header_according_to_protocol(str_describe_header)elif config_dict['header_overload_modify_allow'] & config_dict['describe_header_modify']:

str_describe_header=self.add_overload_header_according_to_protocol(str_describe_header)

self.socket_send.send(str_describe_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the first DESCRIBE response is :')print(msg_recv_dict[0])print('\nnow we will execute second DESCRIBE for auth')

realm_value= 'RTSP SERVER'nonce_value= 'e29027990294f81b941b04a7ac78c196'str_describe_auth_header=self.gen_describe_auth_header(url, realm_value, nonce_value)if config_dict['header_normal_modify_allow'] & config_dict['describe_auth_header_modify']:

str_describe_auth_header=self.add_normal_header_according_to_protocol(str_describe_auth_header)elif config_dict['header_overload_modify_allow'] & config_dict['describe_auth_header_modify']:

str_describe_auth_header=self.add_overload_header_according_to_protocol(str_describe_auth_header)

self.socket_send.send(str_describe_auth_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the second DESCRIBE response is :')print(msg_recv_dict[0])print('\nnow we will execute first SETUP for session')

str_setup_header=self.gen_setup_header(url, realm_value, nonce_value)if config_dict['header_normal_modify_allow'] & config_dict['setup_header_modify']:

str_setup_header=self.add_normal_header_according_to_protocol(str_setup_header)elif config_dict['header_overload_modify_allow'] & config_dict['setup_header_modify']:

str_setup_header=self.add_overload_header_according_to_protocol(str_setup_header)

self.socket_send.send(str_setup_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the first SETUP response is :')print(msg_recv_dict[0])print('\nnow we will execute second SETUP')

session_value= '464314414585882'str_setup_session_header=self.gen_setup_session_header(url, realm_value, nonce_value, session_value)if config_dict['header_normal_modify_allow'] & config_dict['setup_session_header_modify']:

str_setup_session_header=self.add_normal_header_according_to_protocol(str_setup_session_header)elif config_dict['header_overload_modify_allow'] & config_dict['setup_session_header_modify']:

str_setup_session_header=self.add_overload_header_according_to_protocol(str_setup_session_header)

self.socket_send.send(str_setup_session_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the second SETUP response is :')print(print(msg_recv_dict[0]))print('\nnow we wil execute PLAY')

str_play_header=self.gen_play_header(url, realm_value, nonce_value, session_value)if config_dict['header_normal_modify_allow'] & config_dict['play_header_modify']:

str_play_header=self.add_normal_header_according_to_protocol(str_play_header)elif config_dict['header_overload_modify_allow'] & config_dict['play_header_modify']:

str_play_header=self.add_overload_header_according_to_protocol(str_play_header)

self.socket_send.send(str_play_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the PLAY response is :')print(msg_recv_dict[0])print('\nnow we will execute GET_PARAMETER')

str_get_parameter_header= self.gen_get_parameter_header(url, realm_value, nonce_value, session_value, '1')if config_dict['header_normal_modify_allow'] & config_dict['get_parameter_header_modify']:

str_get_parameter_header=self.add_normal_header_according_to_protocol(str_get_parameter_header)elif config_dict['header_overload_modify_allow'] & config_dict['get_parameter_header_modify']:

str_get_parameter_header=self.add_overload_header_according_to_protocol(str_get_parameter_header)

self.socket_send.send(str_get_parameter_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the GET_PARAMETER response is :')print(msg_recv_dict[0])print('\nnow we will execute TEARDOWN to disconnect with server')

str_teardown_header=self.gen_teardown_header(url, realm_value, nonce_value, session_value)if config_dict['header_normal_modify_allow'] & config_dict['teardown_header_modify']:

str_teardown_header=self.add_normal_header_according_to_protocol(str_teardown_header)elif config_dict['header_overload_modify_allow'] & config_dict['teardown_header_modify']:

str_teardown_header=self.add_overload_header_according_to_protocol(str_teardown_header)

self.socket_send.send(str_teardown_header.encode())

msg_recv= self.socket_send.recv(config_dict['buffer_len']).decode()

msg_recv_dict= msg_recv.split('\r\n')print('the GET_PARAMETER response is :')print(msg_recv_dict[0])print('program execute finished, thank you')

self.socket_send.close()def __del__(self):#self.socket_send.close()

pass

if __name__ == '__main__':

rtsp_client=RtspClient()

rtsp_client.exec_full_request()#rtsp_client.exec_force_request()

python rtsp推流_python3实现的rtsp客户端脚本相关推荐

  1. python 配置文件对比_Python3实现配置文件差异对比脚本

    应用场景:配置文件由于升级改动了,我们想看看升级后的配置文件相对于之前的改动了哪些配置项 注意:这个脚本只能检测的配置文件是键值对的形式,就是key=value的形式 我在网上找了好久没找到这一块的案 ...

  2. windows环境下python使用ffmpeg rtsp推流

    rtsp推流 1.下载 rtsp 服务器下载网址: https://github.com/aler9/rtsp-simple-server/releases windows环境下选择windows_a ...

  3. FFmpeg 中 RTSP推流桌面和Android设备延时测试

    文章目录 1. FFMPEG 推流: 1.1 FFmpeg 源码准备 1.2 RTSP 推流服务器 2. 执行流程 2.1 启动服务器 2.2 执行桌面推流 2.3 播放 3. 安卓测试 1. FFM ...

  4. 2.gstreamer USB摄像头RTSP推流

    目录 1.操作系统版本 2.使用gstreamer播放mp4文件 3.采集USB摄像头视频源,并RTSP推流 4.使用RTSP播放器播放 5.注意事项 1.操作系统版本 使用的虚拟机加ubuntu 2 ...

  5. 设置VLC播放器进行RTSP推流桌面(共享桌面)

    设置VLC播放器进行RTSP推流桌面(共享桌面) 一.推流与拉流概念 二.设置推流端 三.设置拉流端(播放端) VLC官网:https://www.videolan.org/ 一.推流与拉流概念 首先 ...

  6. 设置VLC播放器进行RTSP推流视频

    设置VLC播放器进行RTSP推流视频 一.推流与拉流概念 二.设置推流端 三.设置拉流端(播放端) VLC官网:https://www.videolan.org/ 一.推流与拉流概念 首先,做几个名词 ...

  7. 网红主播如何用ENC设备向快手直播伴侣RTSP推流(可多账号多平台推流)

    喜欢用快手直播的网红兄弟姐妹们看过来,这篇文章可以让你们很快的熟悉如何用ENC1设备向快手直播伴侣推流了.快快坐下来,仔细研读,大家都知道,快手直播伴侣是的美颜效果还是不错的,再结合ENC设备可以向多 ...

  8. 使用EasyDarwin+FFmpeg实现rtsp推流

    一.背景 ​ 最近在学习ffmpeg的基本操作,ffmpeg功能非常强大,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec--这是一个用于多个项目中音频和视频的解码器库,以及 ...

  9. live555的安装 RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)

    live555是一个开源的软件,主要用来生成rtsp,rtp和sip服务器和客户端的软件.前几天需要看一下vlc中的rtsp的功能,在vlc中 rtp和rtsp的功能都是使用live555中的函数来生 ...

最新文章

  1. jvm:运行时数据区
  2. lenovo vantage工具栏无反应 电池图标单击无法显示状态栏
  3. python文本聚类分析_python机器学习kmeans算法——对文本进行聚类分析
  4. 泰山挑夫1(菜鸟题解)
  5. Spring Boot细节挖掘(Docker部署项目)
  6. 在asp.net如何取得ActiveDirectory域中用户的信息,比如工号,邮件地址等等
  7. html代码表白_七夕表白代码,樱花特效+爱心特效+花瓣+评论留言功能等
  8. lin接口 连接计算机,db9接口(lin接口db9定义)
  9. robot framework-ride导入Selenium2Library报错,已解决
  10. 2022CCPC网络预选赛题解
  11. p5.js之Q版人物绘制
  12. 最好用的 7 款 Vue admin 后台管理系统测评
  13. mongos魔兽世界模拟器
  14. C#调用Windows图片和传真查看器打开图片
  15. 微软将要求供应商提供带薪育儿假;倪光南谈中国软件业机遇,称已出现由中方主导的开源社区...
  16. 微生物组-扩增子16S分析第10期(报名直播课免费参加线下2020.12)
  17. DS18B20数字温度计使用(转)
  18. Python 计算两个连通子图距离_复杂网络分析之python利器NetworkX
  19. SSO单点登录-基于cookie的单点登录
  20. 【Redis】Redis数据结构与对象(一)简单动态字符串(SDS)

热门文章

  1. qsv,nivdia解码花屏研究
  2. 工业自动化控制通讯协议库,工业自动软件必备的基本程序
  3. 《精益数据分析》内容概要
  4. TUV莱茵与海康睿和签署电梯物联网战略合作协议
  5. Lumerical练习2-建模练习2
  6. Mysql 查询指定数据在查询数据列表中排名问题
  7. 【面试必会】带你快速通过字节跳动面试,跳槽大厂必看!
  8. 前端开发中icon图标使用的那些门道儿
  9. 中国联通:云计算必须开放、开源
  10. 2011.11.17,Google已经正式推出Google音乐服务(Google Music)