basessh2.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. # -*- coding:utf-8 -*-
  2. import os
  3. import sys
  4. import time
  5. import datetime
  6. import socket
  7. import hashlib # md5验证;
  8. from ssh2.session import Session
  9. from ssh2.sftp import LIBSSH2_FXF_READ, LIBSSH2_SFTP_S_IRUSR
  10. class baseSSH2:
  11. def __init__(self):
  12. self.__user = ""
  13. self.__pwd = ""
  14. self.__host = ""
  15. self.__port = 22
  16. '''
  17. 函数:创建tcp sock连接;
  18. 参数:无
  19. 返回:成功创建tcp连接返回sock,否则返回None
  20. 注意:创建成功后的sock,在外部使用完后必须调用sock.close()释放;
  21. '''
  22. def __create_sock(self):
  23. # 创建tcp连接;
  24. try:
  25. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  26. sock.connect((self.__host, int(self.__port))) # 没有返回值;
  27. return sock
  28. except Exception, e:
  29. print u'创建ssh2 socket失败', e
  30. return None
  31. '''
  32. 函数:初始化ssh2所需参数;
  33. 参数:user、pwd、host、port
  34. 返回:无
  35. '''
  36. def init_ssh2(self, user, pwd, host, port=22):
  37. self.__host = host
  38. self.__port = port
  39. self.__user = user
  40. self.__pwd = pwd
  41. '''
  42. 函数:执行命令;
  43. 参数:cmd
  44. 返回:执行成功,返回True及执行结果;
  45. '''
  46. def execute_cmd(self, cmd):
  47. print u"ssh2.execute_cmd=",cmd
  48. sock = self.__create_sock()
  49. if sock is None:
  50. return False, ""
  51. # 创建ssh2会话连接;
  52. session = Session()
  53. # 关联tcp socket;
  54. if session.handshake(sock) is None:
  55. sock.close()
  56. print u'建立ssh2 会话失败'
  57. return False, ""
  58. # 以用户+密码方式建立认证连接;
  59. if session.userauth_password(self.__user, self.__pwd) is None:
  60. sock.close()
  61. print u'登录ssh2 会话失败'
  62. return False, ""
  63. strdata = ''
  64. # 创建会话通道;
  65. channel = session.open_session()
  66. channel.execute(cmd)
  67. size, data = channel.read()
  68. strdata = data
  69. while size > 0:
  70. size, data = channel.read()
  71. strdata += data
  72. channel.close()
  73. # print("Exit status: %s" % channel.get_exit_status())
  74. sock.close()
  75. return True if channel.get_exit_status() == 0 else False, strdata
  76. '''
  77. 函数:下载文件;
  78. 参数:ftp_path要下载的文件路径, local_path要保存的文件路径;
  79. 返回:执行成功,返回True;
  80. '''
  81. def sftp_download(self, ftp_path, local_path):
  82. sock = self.__create_sock()
  83. if sock is None:
  84. return False
  85. # 创建ssh2会话连接;
  86. session = Session()
  87. # 关联tcp socket;
  88. if session.handshake(sock) is None:
  89. sock.close()
  90. print u'建立ssh2 会话失败'
  91. return False
  92. # 以用户+密码方式建立认证连接;
  93. if session.userauth_password(self.__user, self.__pwd) is None:
  94. sock.close()
  95. print u'登录ssh2 会话失败'
  96. return False
  97. sftp = session.sftp_init()
  98. # now = datetime.time()
  99. # print("Starting read for remote file %s" % ftp_path)
  100. try:
  101. with sftp.open(ftp_path, LIBSSH2_FXF_READ, LIBSSH2_SFTP_S_IRUSR) as fh, open(local_path, 'wb+') as lh:
  102. for size, data in fh:
  103. lh.write(data)
  104. # print 'download size=',size
  105. lh.close()
  106. # print("Finished file read in %s" % (datetime.time() - now))
  107. sock.close()
  108. return True
  109. except Exception, e:
  110. print u'下载失败:',e
  111. return False
  112. '''
  113. 函数:计算文件md5值;
  114. 参数:file要计算的文件路径;
  115. 返回:执行成功返回md5值,否则返回None;
  116. '''
  117. def get_md5_sum(self, sftp_file):
  118. cmd = 'md5sum %s' % sftp_file
  119. boolean, data = self.execute_cmd(cmd)
  120. if boolean is False:
  121. return None
  122. # 分组;
  123. str_list = data.split(' ')
  124. if str_list.__len__() != 2:
  125. return None
  126. return str_list[0]
  127. '''
  128. 函数:下载文件,并验证md5是否正确;
  129. 参数:ftp_path要下载的文件路径, local_path要保存的文件路径;
  130. 返回:执行成功,返回True;
  131. '''
  132. def sftp_download_md5(self, ftp_path, local_path):
  133. # 先计算md5值;
  134. sftp_md5 = self.get_md5_sum(ftp_path)
  135. if sftp_md5 is None:
  136. print 'sftp_md5值空'
  137. return False
  138. print "SFTP MD5=", sftp_md5
  139. # 下载文件后计算;
  140. if self.sftp_download(ftp_path, local_path) is True:
  141. local_md5 = ""
  142. md5_local = hashlib.md5()
  143. time.sleep(5)
  144. file_data = []
  145. if os.path.exists(local_path):
  146. with open(local_path, mode='rb') as f:
  147. while True:
  148. data = f.read(8192)
  149. if not data:
  150. break
  151. md5_local.update(data)
  152. local_md5 = md5_local.hexdigest()
  153. print u"本地MD5=", local_md5
  154. return True if sftp_md5 == local_md5 else False
  155. print u'下载文件失败'
  156. return False
  157. if __name__ == "__main__":
  158. host = "10.201.251.254"
  159. user = "wjf"
  160. pwd = "wjf2019"
  161. myssh2 = baseSSH2()
  162. myssh2.init_ssh2(user, pwd, host)
  163. # cmd = "md5sum /home/RT2841_2851_dailybuild/DailyBuild_RT2851_0509/signed-ota_rt2851_update.zip"
  164. # bolean, data = myssh2.execute_cmd(cmd)
  165. # print data.split(' ')[0]
  166. # print u'MD5值=', myssh2.get_md5_sum(
  167. # "/home/RT2841_2851_dailybuild/DailyBuild_RT2851_0509/signed-ota_rt2851_update.zip")
  168. # myssh2.sftp_download("rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/build.prop", "D:\\sat\\build.prop")
  169. # myssh2.sftp_download("/home/RT2841_2851_dailybuild/DailyBuild_RT2851_0509/signed-ota_rt2851_update.zip", "D:\\sat\\a.img")
  170. if myssh2.sftp_download_md5("/home/RT2841_2851_dailybuild/DailyBuild_RT2851_0509/signed-ota_rt2851_update.zip", "D:\\sat\\b.img"):
  171. print u"下载文件成功"