网络编程

网络编程

  • 网络
  • 网络协议:一套规则
  • 网络模型:
    • 七层模型
      • 物理层
      • 数据链路层
      • 网络层
      • 传输层
      • 会话层
      • 表示层
      • 应用层
    • 四层模型-------实际应用
      • 链路层
      • 网络
      • 传输层
      • 应用层
  • 每一层都有相应的协议负责交换信息或者协同工作
  • TCP/IP 协议族
  • IP地址:负责在网络上唯一定位一个机器
    • IP地址分ABCDE类
    • 是由四个数字段组成,每个数字段的取值是0-255
    • 192.168.×××.×××,局域网ip
    • 127.0.0.1,本机
    • IPv4,IPv6
  • 端口
    • 范围:0-65535
      - 知名端口:0-1023
      - 非知名端口:1024-65535

TCP/UDP协议

  • UDP:非安全的不面向链接的传输
    • 安全性差
    • 大小限制64KB
    • 没有顺序
    • 速度快
  • TCP:基于链接的通信
  • SOCKET通信
    • socket(套接字)
    • IP+端口定位
    • 分为UDP和TCP
    • 客户端client,服务端server

UDP编程

  • Server端编程
    1. 建立 socket,socket是负责具体通信的一个实例
    2. 绑定,为创建的socket指派固定的端口和ip地址
    3. 接受对方发送的内容
    4. 给对方发送反馈,非必须步骤
  • Client端流程
    1. 建立通信的socket
    2. 发送内容到指定服务器
    3. 接受服务器给定的反馈内容
  • 代码示例
    • 服务端
import socket
# 模拟服务器的函数
def serverFunc():
   # 建立socket
   # socket.AF_INET:使用ipv4协议族
   # socket.SOCK_DGRAM:使用UDP通信
   sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
   '''
   绑定ip和port
   127.0.0.1:代表机器本身
   6666:端口号
   地址是一个tuple类型,(ip,port)
   '''
   addr = ('127.0.0.1',6666)
   sock.bind(addr)
   '''
   接受对方消息
   等待方式为死等
   recvfrom接受的返回值是一个tuple,前一项表示数据,后一项表示地址
   参数的含义是缓冲区大小
   '''
   data,addr = sock.recvfrom(500)
   print(data)
   print(type(data))
   '''
   发送过来的数据是bytes格式,必须通过解码才能得到str格式内容
   decode默认参数是utf8
   '''
   text = data.decode()
   print(type(text))
   print(text)
   '''
   给对方返回消息
   发送的数据需要编码成bytes格式
   '''
   rsp = 'ren shi zhe ge shi jie'
   data = rsp.encode()
   sock.sendto(data,addr)
   
if __name__ == '__main__':
   print('starting server...........')
   serverFunc()
   print('Ending server.........')
  • 客户端
import socket
def clientFunc():
    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    text = 'gan fan zhe ge shi jie'
    #发送的数据必须是bytes格式
    data = text.encode()
    #发送
    sock.sendto(data,('127.0.0.1',6666))
    #接受
    data,addr = sock.recvfrom(500)
    text = data.decode()
    print(text)
if __name__ == '__main__':
    clientFunc()

运行结果
服务端:

starting server...........
b'gan fan zhe ge shi jie'
<class 'bytes'>
<class 'str'>
gan fan zhe ge shi jie
Ending server.........

客户端:

ren shi zhe ge shi jie

  • 服务器程序要求永久运行,一般用死循环处理

TCP编程

  • 面向链接的传输,即每次传输之前需要先建立一个链接
  • Server端的编写流程
    1. 建立socket负责具体通信,
    2. 绑定端口和地址
    3. 监听接入的访问socket
    4. 接受访问的socket,可以理解为接受访问即建立了一个通讯的链接通路
    5. 接受对方的发送内容
    6. 发送反馈内容,非必须
    7. 关闭链接通路
  • Client端流程
    1. 建立通信socket
    2. 链接对方,请求跟对方建立通路
    3. 发送内容到对方服务器
    4. 接受对方反馈
    5. 关闭链接通路
  • 代码示例
    服务端:
import socket

def tcp_srv():

    # socket.AF_INET:含义同UDP一致
    # socket.SOCK_DGRAM:表明使用tcp进行通信
    
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    '''
    绑定ip和port
    127.0.0.1:代表机器本身
    6666:端口号
    地址是一个tuple类型,(ip,port)
    '''
    addr = ('127.0.0.1',66)
    sock.bind(addr)
    
    #监听接入的访问socket
    sock.listen()
    
    while True:
        
        #接受访问的socket,建立了一个通讯的链接通路
        
        skt,addr = sock.accept()
        
        #受对方的发送内容,利用接受到的socket接受内容
        
        msg = skt.recv(500)
        msg = msg.decode()
        rst = 'Received msg:{0} from {1}'.format(msg,addr)
        print(rst)
        skt.send(rst.encode())
        
        #关闭链接通路
        skt.close()
if __name__ == '__main__':
    print('starting tcp server...........')
    tcp_srv()
    print('Ending tcp server.........')

客户端:

import socket
def tcp_clt():
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #链接对方,请求跟对方建立通路
    addr = ('127.0.0.1',66)
    sock.connect(addr)
    #发送内容到对方服务器
    msg = 'gan fan zhe ge shi jie'
    sock.send(msg.encode())
    #接受对方反馈
    rst = sock.recv(500)
    print(rst.decode())
    #关闭链接通路
    sock.close()
    
if __name__ == '__main__':
    tcp_clt()

运行结果:
服务端

starting tcp server...........
Received msg:gan fan zhe ge shi jie from ('127.0.0.1', 59304)

客户端

Received msg:gan fan zhe ge shi jie from ('127.0.0.1', 59304)

FTP编程

  • FTP(FileTransferProtocal)文件传输协议
  • 用途:定制一些特殊的上传下载文件服务
  • 用户分类:登录FTP服务器必须有一个账号
    • Real账户:注册账户
    • Guest账户:临时对某些账户行为授权
    • Anonymous:匿名账户,允许任何人
  • FTP工作流程
    1. 客户端链接远程主机上的FTP服务器
    2. 客户端输入用户名和密码(或者Anonymous和电子邮箱地址)
    3. 客户端和服务器进行各种文件传输和信息查询操作
    4. 客户端从远程FTP服务器退出,结束传输
  • FTP文件表示
    • 分三段表示FTP上的文件
    • HOST:主机地址,类似于:ftp.mozilla.org,以ftpk开头
    • DIR:目录,表示文件所在本地的路径
    • File:文件名称
    • 如果想要完整精确的表示一个FTP上的文件,需将上述三部分组合

mail编程

邮件工作流程

  • MUA(MailUserAgent)邮件用户代理
  • MTA(MailTransferAgent)邮件传输代理
  • MDA(MailDeliveryAgent)邮件投递代理
  • 流程
    1. MUA -> MTA,邮件已经在服务器上
    2. qq MTA -> ..........................->sina MTA,邮件到新浪服务器上
    3. sina MTA -> sina MDA,此时邮件到自己的邮箱
    4. sina MDA -> MUA,邮件下载到本地电脑
  • 编写程序
    • 发送:MUA->MTA with SMTP:SimpleMailTransferProtocal
    • 接受:MDA->MUA with POP3 and IMAP:PostOfficeProtocal v3 and InternetMessageAccessProtocal v4
  • 准备工作
    • 注册邮箱
    • 第三方邮箱需要特殊设置,qq邮箱为例
      • 进入设置中心
      • 取得授权码
  • python for mail
  • 发送邮件
    • SMTP协议负责发送邮件
      • 使用email模块构建邮件
      • 使用smtplib模块发送邮件
  • 代码示例
    • 纯文本邮件
import smtplib
from email.mime.text import MIMEText
'''
MIMEText三个主要参数
1.邮件内容
2.MIME子类型,在此案例我们用plain表示text类型
3.邮件编码格式
'''
msg = MIMEText('Hello,hi,how are u','plain','utf-8')
#发送email地址
from_addr = '515641874@qq.com'
#申请设置后的授权码
from_pwd = 'fcxabqrarjhfcach'
#收件人信息
to_addr = '515641874@qq.com'
#qq邮箱SMTP服务器地址
smtp_srv = 'smtp.qq.com'
try:
    #服务器地址需要编码成bytes格式
    #服务器接受的访问端口465
    srv = smtplib.SMTP_SSL(smtp_srv.encode(),465)
    #登录邮箱发送
    srv.login(from_addr,from_pwd)
    '''
    发送邮件
    三个参数
    1.发送地址
    2.接受地址,list格式
    3.发送内容,字符串发送
    '''
    srv.sendmail(from_addr,[to_addr],msg.as_string())
    srv.quit()
except Exception as e:
    print(e)
  • html邮件,把邮件的subtype设为html
import smtplib
from email.mime.text import MIMEText

mail_content = """
            <!DOCTYPE HTML>
            <html lang='en'>
            <head>
                <meta charset='UTF-8'>
                <title>Title</title>
            </head>
            <body>
            <h1>这是一封HTML格式的邮件</h1>
            </body>
            </html>
            """
msg = MIMEText(mail_content,'html','utf-8')
from_addr = '515641874@qq.com'
from_pwd = 'fcxabqrarjhfcach'
to_addr = '515641874@qq.com'
smtp_srv = 'smtp.qq.com'
try:
    srv = smtplib.SMTP_SSL(smtp_srv.encode(),465)
    srv.login(from_addr,from_pwd)
    srv.sendmail(from_addr,[to_addr],msg.as_string())
    srv.quit()
except Exception as e:
    print(e)
  • 带附件的邮件
    • 一封邮件涉及多个部分,需要使用MIMEMultipart格式创建
    • 添加一个MIMEText正文
    • 添加一个MIMEBase或者MIMEText作为附件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEBase,MIMEMultipart

mail_mul = MIMEMultipart()
#构建邮件正文
mail_text = MIMEText('Hello,hanjingbin','plain','utf-8')
#把构建好的邮件正文添加到邮件中
mail_mul.attach(mail_text)
'''
构建附件需要从本地读入附件
以rb格式打开一个本地文件
'''
with open('C:/users/51564/Desktop/123.html','rb') as f:
    s = f.read()
    #设置附件的MIME和邮件名
    m = MIMEText(s,'base64','utf-8')
    m['Content-Type'] = 'application/octet-stream'
    m['Content-Dispositon'] = "attachment;filename = '123.html'"
    mail_mul.attach(m)
from_addr = '515641874@qq.com'
from_pwd = 'fcxabqrarjhfcach'
to_addr = '515641874@qq.com'
smtp_srv = 'smtp.qq.com'
try:
    srv = smtplib.SMTP_SSL(smtp_srv.encode(),465)
    srv.login(from_addr,from_pwd)
    srv.sendmail(from_addr,[to_addr],mail_mul.as_string())
    srv.quit()
except Exception as e:
    print(e)
  • 添加邮件头、抄送等信息
    • mail['From'] 表示发送者信息,姓名和邮件地址
    • mail['To']表示接受者信息,姓名和邮件地址
    • mail['Subject']表示摘要或主题信息
import smtplib
from email.mime.text import MIMEText
from email.header import Header

msg = MIMEText('Hello,hi,how are u','plain','utf-8')

header_from =Header('我从哪里来<wocongnalai@qq.com>','utf-8')
header_to = Header('我要到哪里去<qunalia@qq.com>','utf-8')
header_sub = Header('我是谁','utf-8')

msg['From'] = header_from
msg['To'] = header_to
msg['Subject'] = header_sub


from_addr = '515641874@qq.com'
from_pwd = 'fcxabqrarjhfcach'
to_addr = '515641874@qq.com'
smtp_srv = 'smtp.qq.com'
try:
    srv = smtplib.SMTP_SSL(smtp_srv.encode(),465)
    srv.login(from_addr,from_pwd)
    srv.sendmail(from_addr,[to_addr],msg.as_string())
    srv.quit()
except Exception as e:
    print(e)
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容