Python 网络客户端编程

我会带着你远行 2022-06-03 09:52 286阅读 0赞

如果我们把因特网简化成一个数据交换中心,数据交换的参与者是一个服务提供者和一个服务的使用者。服务器就是服务者,或叫生产者,它提供服务,一般只有一个服务器,和多个消费者。因特网中最流行的事情就是文件的交换。文件交换无处不在。

文本传输协议(FTP)主要用于匿名下载公共文件,也可以用于在两台电脑之间传输文件。

下面这个例子简单写了一个连接FTP并下载文件

  1. #!/usr/bin/ env python
  2. #coding=utf-8
  3. import ftplib
  4. import os
  5. import socket
  6. HOST = 'ftp.sjtu.edu.cn'
  7. DIRN = 'pub/rfc/fyi/'
  8. FILE = 'fyi10.txt'
  9. def main():
  10. try:
  11. f = ftplib.FTP(HOST)
  12. except (socket.error, socket.gaierror), e:
  13. print('ERROR: cannot reach "%s"' % HOST)
  14. return
  15. print('***Connected to host "%s"' % HOST)
  16. try:
  17. f.login()
  18. except ftplib.error_perm:
  19. print('ERROR: cannot login anonymously')
  20. f.quit()
  21. return
  22. print('*** Logged in as "anonymously"')
  23. try:
  24. f.cwd(DIRN)
  25. except ftplib.error_perm:
  26. print('ERROR: cannot cd to "%s"' % DIRN)
  27. f.quit()
  28. return
  29. print('*** Changed to "%s" folder' %DIRN)
  30. try:
  31. f.retrbinary('RETR %s' %FILE, open(FILE, 'wb').write)
  32. except ftplib.error_perm:
  33. print('ERROR: cannot read file "%s"' % FILE)
  34. os.unlink(FILE)
  35. else:
  36. print('*** Downloaded "%s" to CWD' %FILE)
  37. f.quit()
  38. return
  39. if __name__ == '__main__':
  40. main()

网络新闻传输协议(NNTP)与FTP的操作方式很像,而且简单的多。FTP需要用不同的端口来做登录,数据传输和控制,而NNTP只使用一个标准端口119来做通讯。

我们来下载Python语言新闻组com.lang.python里的一篇文章。

  1. #!/usr/bin/ env python
  2. #coding=utf-8
  3. import nntplib
  4. import socket
  5. HOST = 'your.nntp.server'
  6. GRNM = 'group name'
  7. USER = 'user'
  8. PASS = 'password'
  9. def displayFirst20(data):
  10. '''
  11. 获取 data 内前20个有意义的行
  12. '''
  13. print('*** first (<=20) meaningful lines:\n')
  14. count = 0 #创建一个计数器
  15. '''
  16. 获取文章行列表,rstrip()方法删除字符串尾随的空格
  17. '''
  18. lines = (line.rstrip() for line in data)
  19. lastBlank = True #上一行为空的标识,作为判断条件
  20. for line in lines:
  21. if line:
  22. lower = line.lower() #将 line 内容转换小写
  23. if (lower.startswith('>') and not \
  24. lower.startswith('>>>')) or \
  25. lower.startswith('|') or \
  26. lower.startswith('in article') or \
  27. lower.endswith('writes:') or \
  28. lower.endswith('wrote:'):
  29. continue
  30. if not lastBlank or (lastBlank and line): #如果上一行不是空行,或者上一行为空行,但当前行不为空时
  31. print(' %s' % line)
  32. if line: #如果当前行不为空,计数器+1,lastBank 为 false,上一行不为空
  33. count += 1
  34. lastBlank = False
  35. else:
  36. lastBlank = True
  37. if count == 20:
  38. break
  39. def main():
  40. try:
  41. n = nntplib.NNTP(HOST) #尝试连接 NNTP 服务器,如果失败就退出
  42. #,user=USER,password=PASS
  43. except socket.gaierror as e:
  44. print('ERROR:cannot reach host "%s"' % HOST)
  45. print(' ("%s")' % eval(str(e))[1])
  46. return
  47. except nntplib.NNTPPermanentError as e:
  48. print('ERROR:access denied on "%s"' % HOST)
  49. print(' %s' % str(e))
  50. return
  51. print('****connected to host "%s"' % HOST)
  52. try:
  53. rsp, ct , fst, lst, grp = n.group(GRNM) #尝试读取指定的新闻组
  54. except nntplib.NNTPTemporaryError as e: #如果新闻组不存在、或服务器没有保存这个新闻组,或需要身份验证等就退出
  55. print('ERROR: cannot load group "%s"' % GRNM)
  56. print(' "%s"' % str(e))
  57. print(' server may require authentication')
  58. print(' uncomment/edit login line above')
  59. n.quit()
  60. return
  61. except nntplib.NNTPTemporaryError as e:
  62. print('ERROR: group "%s" unavaliable' % GRNM)
  63. print(' %s' % str(e))
  64. n.quit()
  65. return
  66. print('*** found newsgroup "%s"' % GRNM)
  67. rng = '%s-%s' % (lst,lst) #给定想要提取消息头的文章范围,因为要获取最后一条信息,所以范围是最后--最后
  68. rsp, frm = n.xhdr('from',rng) #获取制定范围的文章信息:服务器响应,指定范围的消息头列表 frm-文章来源
  69. rsp, sub = n.xhdr('subject',rng) #sub 文章子标题
  70. rsp, dat = n.xhdr('date',rng) #文章主文本
  71. print('''
  72. *** found last article (#%s):
  73. from:%s
  74. subject:%s
  75. date:%s
  76. ''' % (lst, frm[0][1], sub[0][1], dat[0][1]))
  77. '''
  78. 由于上边选取的范围只有最后一个,所以只获取第一个元素【0】,数
  79. 据元素是一个长度为2的元组,包含文章编号和数据字符串,因此数据字符串frm[0][1]
  80. '''
  81. rsp, anum, mid, data = n.body(lst) #根据最后一篇文章的 id 获取(服务器响应信息,文章编号,消息 id,文章所有行)
  82. displayFirst20(data) #调用方法只保存前20个有意义的行
  83. n.quit() #退出
  84. if __name__ == '__main__':
  85. main()

电子邮件e-mail

SMTP(简单邮件传输协议)是在因特网上MTA之间用于信息交换的最常用的MTS。它被MTA用来把e-mail从一台主机传送到另一台主机。在发送email的时候,必须要连接到一个外部的SMTP服务器,这时,你的邮件程序是一个SMTP客户端。

POP(邮局协议),让用户的工作站可以访问邮箱服务器里的邮件。邮件要能从工作站通过SMTP发送到邮件服务器。POP3指的是POP协议最常用的第三版。

  1. #!/usr/bin/ env python
  2. #coding=utf-8
  3. from smtplib import SMTP
  4. from smtplib import SMTPRecipientsRefused
  5. from poplib import POP3
  6. from time import sleep
  7. import sys
  8. smtpserver = 'smtp.163.com'
  9. pop3server = 'pop.163.com'
  10. emailaddr = 'username@163.com'
  11. username = 'username'
  12. password = 'password'
  13. # 组合邮件格式
  14. origHeaders = ['From: username@163.com',
  15. 'To: username@163.com',
  16. 'Subject: test msg']
  17. origBody = ['test ', 'smtp', 'pop3']
  18. origMsg = '\r\n\r\n'.join(['\r\n'.join(origHeaders), '\r\n'.join(origBody)])
  19. # 发送邮件部分
  20. def sendMail():
  21. sendSer = SMTP(smtpserver)
  22. sendSer.set_debuglevel(1)
  23. print sendSer.ehlo()[0] # 服务器属性等
  24. sendSer.login(username, password) # 邮箱需要验证
  25. try:
  26. errs = sendSer.sendmail(emailaddr, emailaddr, origMsg)
  27. except SMTPRecipientsRefused:
  28. print 'server refused....'
  29. sys.exit(1)
  30. sendSer.quit()
  31. assert len(errs) == 0, errs
  32. print '******send a mail ....OK!'
  33. sleep(10) # 等待10秒
  34. print '******Now get the mail .....*******'
  35. # 开始接收邮件
  36. def receiveMail():
  37. revcSer = POP3(pop3server)
  38. revcSer.user(username)
  39. revcSer.pass_(password)
  40. rsp, msg, siz = revcSer.retr(revcSer.stat()[0])
  41. sep = msg.index('')
  42. if msg:
  43. for i in msg:
  44. print i
  45. revcBody = msg[sep + 1:]
  46. assert origBody == revcBody
  47. print '******successful get ....'
  48. def main():
  49. sendMail()
  50. receiveMail()
  51. if __name__ == '__main__':
  52. main()

发表评论

表情:
评论列表 (有 0 条评论,286人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Python 网络客户编程

    如果我们把因特网简化成一个数据交换中心,数据交换的参与者是一个服务提供者和一个服务的使用者。服务器就是服务者,或叫生产者,它提供服务,一般只有一个服务器,和多个消费者。因特网中