python学习笔记-网络编程

#=========================网络编程=====================
# 网络:
# 网络协议: 一套规则
# 网络模型:
  # 七层模型,ISO
  # 四层模型,TCP/IP

# 每一层都有相应的协议负责交换信息或者协同工作
# TCP/IP 协议族
# IP地址:负责在网络上唯一定位一个机器
# 端口
    # 范围: 0#65535
        # 知名端口:0#1023
        # 非知名端口:1024#
        
# TCP/UDP协议
# UDP:非安全的不面向链接的传输
    # 安全性差
    # 大小限制64kb
    # 没有顺序
    # 速度快
# TCP
    # 基于链接的通信
    
#=========================SOCKET编程-UDP=========================
    # socket(套接字): 是一个网络通信的端点, 能实现不同主机的进程通信,网络大多基于Socket通信
    # 通过IP+端口定位对方并发送消息的通信机制
    # 分为UDP和TCP
    # 客户端Client: 发起访问的一方
    # 服务器端Server:接受访问的一方
# UDP 编程
    # Server端流程
            1. 建立socket,socket是负责具体通信的一个实例
            2. 绑定,为创建的socket指派固定的端口和ip地址
            3. 接受对方发送内容
            4. 给对方发送反馈,此步骤为非必须步骤
    # Client端流程
            1. 建立通信的socket
            2. 发送内容到指定服务器
            3. 接受服务器给定的反馈内容
    # 服务器案例:
    '''
    Server端流程
     1. 建立socket,socket是负责具体通信的一个实例
     2. 绑定,为创建的socket指派固定的端口和ip地址
     3. 接受对方发送内容
     4. 给对方发送反馈,此步骤为非必须步骤
    '''

    # socket模块负责socket编程
    import socket

    def serverFunc():
        # 1. 建立socket
        # socket.AF_INET:使用ipv4协议族
        # socket.SOCK_DGRAM: 使用UDP通信
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        # 2. 绑定ip和port
        # 127.0.0.1: 这个ip地址代表的是机器本身
        # 7852: 随手指定的端口号
        # 地址是一个tuple类型,(ip, port)
        addr = ("127.0.0.1", 7852 )
        sock.bind( addr )

        # 接受对方消息
        # 等待方式为死等, 没有其他可能性
        # recvfrom接受的返回值是一个tuple,前一项表示数据,后一项表示地址
        # 参数的含义是缓冲区大小
        # rst = sock.recvfrom(500)
        data, addr = sock.recvfrom(500)
        
        # 发送过来的数据是bytes格式,必须通过解码才能得到str格式内容
        # decode默认参数是utf8
        text = data.decode()
        print(text)

        # 给对方返回的消息
        rsp = "return massage:get it"

        # 发送的数据需要编码成bytes格式
        # 默认是utf8
        data = rsp.encode()
        sock.sendto(data, addr)

    if __name__ == '__main__':
        # 服务器程序要求永久运行,一般用死循环处理
        while 1:
        try:
            serverFunc()
        except Exception as e:
            print(e)
        time.sleep(1)
        
    # 客户端案例:
   import socket

    '''
    - Client端流程
                1. 建立通信的socket
                2. 发送内容到指定服务器
                3. 接受服务器给定的反馈内容
    '''

    def clientFunc():

        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        text = "go go !"
        # 发送的数据必须是bytes格式
        data = text.encode()
        # 发送
        sock.sendto(data,  ("127.0.0.1", 7852))
        data, addr  = sock.recvfrom(200)
        data = data.decode()
        print(data)
    if __name__ == '__main__':
        clientFunc()

    
#=========================SOCKET编程-TCP=========================
    # 面向链接的传输,即每次传输之前需要先建立一个链接
     # 客户端和服务器端两个程序需要编写
     # Server端的编写流程
         1. 建立socket负责具体通信,这个socket其实只负责接受对方的请求,真正通信的是链接后从新建立的socket
         2. 绑定端口和地址
         3. 监听接入的访问socket
         4. 接受访问的socket,可以理解接受访问即建立了一个通讯的链接通路
         5. 接受对方的发送内容,利用接收到的socket接收内容
         6. 如果有必要,给对方发送反馈信息
         7. 关闭链接通路
     # Client端流程
          1. 建立通信socket
          2. 链接对方,请求跟对方建立通路
          3. 发送内容到对方服务器
          4. 接受对方的反馈
          5. 关闭链接通路
  # TCP服务端案例:
  import socket
    def  tcp_srv():
        # 1. 建立socket负责具体通信,这个socket其实只负责接受对方的请求,真正通信的是链接后从新建立的socket
        # 需要用到两个参数
        # AF_INET: 含义同udp一致
        # SOCK_STREAM: 表明是使用的tcp进行通信
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2. 绑定端口和地址
        # 此地址信息是一个元祖类型内容,元祖分两部分,第一部分为字符串,代表ip,第二部分为端口,是一个整数,推荐大于10000
        addr = ("127.0.0.1", 8998)
        sock.bind(addr)
        # 3. 监听接入的访问socket
        sock.listen()

        while True:
            # 4. 接受访问的socket,可以理解接受访问即建立了一个通讯的链接通路
            # accept返回的元祖第一个元素赋值给skt,第二个赋值给addr
            skt,addr = sock.accept()
            # 5. 接受对方的发送内容,利用接收到的socket接收内容
            # 500代表接收使用的buffersize
            #msg = skt.receive(500)
            msg = skt.recv(500)
            # 接受到的是bytes格式内容
            # 想得到str格式的,需要进行解码
            msg = msg.decode()

            rst = "Received msg: {0} from {1}".format(msg, addr)
            print(rst)
            # 6. 如果有必要,给对方发送反馈信息
            skt.send(rst.encode())

            # 7. 关闭链接通路
            skt.close()

        if __name__ == "__main__":
            print("Starting tcp server.......")
            tcp_srv()
            print("Ending tcp server.......")
            
    # TCP客户端案例:
    import socket
    def tcp_clt():
        # 1. 建立通信socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2. 链接对方,请求跟对方建立通路
        addr = ("127.0.0.1", 8998)
        sock.connect(addr)
        # 3. 发送内容到对方服务器
        msg = "I love wangxiaojing"
        sock.send(msg.encode())
        # 4. 接受对方的反馈
        rst =  sock.recv(500)
        print(rst.decode())
        # 5. 关闭链接通路
        sock.close()

if __name__ == "__main__":
    tcp_clt()

#=========================FTP编程=========================
# FTP(FileTransferProtocal)文件传输协议
# 用途: 定制一些特殊的上传下载文件的服务
# 用户分类: 登陆FTP服务器必须有一个账号
    # Real账户: 注册账户
    # Guest账户: 可能临时对某一类人的行为进行授权
    # Anonymous账户: 匿名账户,允许任何人
# FTP工作流程
    1. 客户端链接远程主机上的FTP服务器
    2. 客户端输入用户名和密码(或者“anonymous”和电子邮件地址)
    3. 客户端和服务器进行各种文件传输和信息查询操作
    4. 客户端从远程FTP服务器退出,结束传输   
    
# FTP文件表示
    # 分三段表示FTP服务器上的文件
    # HOST: 主机地址,类似于 ftp.mozilla.org, 以ftp开头
    # DIR:目录, 表示文件所在本地的路径,例如 pub/android/focus/1.1#RC1/ 
    # File: 文件名称, 例如 Klar#1.1#RC1.apk
    # 如果想完整精确表示ftp上某一个文件,需要上述三部分组合在一起
# FTP案例:
    # 需要导入相应包,主要是ftplib
    import ftplib # 关于FTP的操作都在这个包里边
    import os
    import socket

    # 三部分精确表示在ftp服务器上的某一个文件
    # 好多公开ftp服务器访问会出错或者没有反应
    HOST = "ftp.acc.umu.se"
    DIR = 'Public/EFLIB/'
    FILE = 'README'

    # 1. 客户端链接远程主机上的FTP服务器
    try:
        f = ftplib.FTP()
        # 通过设置调试级别可以方便调试
        f.set_debuglevel(2)
        # 链接主机地址
        f.connect(HOST)
    except Exception as e:
        print(e)
        exit()
    print("***Connected to host {0}".format(HOST))

    # 2. 客户端输入用户名和密码(或者“anonymous”和电子邮件地址)
    try:
        # 登录如果没有输入用户信息,则默认使用匿名登录
        f.login()
    except Exception as e:
        print(e)
        exit()
    print("***Logged in as 'anonymous'")

    # 3. 客户端和服务器进行各种文件传输和信息查询操作
    try:
        # 更改当前目录到指定目录
        f.cwd(DIR)
    except Exception as e:
        print(e)
        exit()
    print("*** Changed dir to {0}".format(DIR))

    try:
        # 从FTP服务器上下载文件
        # 第一个参数是ftp命令
        # 第二个参数是回调函数
        # 此函数的意思是,执行RETR命令,下载文件到本地后,运行回调函数
        f.retrbinary('RETR {0}'.format(FILE), open(FILE, 'wb').write)
    except Exception as e:
        print(e)
        exit()

    # 4. 客户端从远程FTP服务器退出,结束传输
    f.quit()
    
#=========================Mail编程=========================
## 电子邮件的历史
# 起源
    # 1969 Leonard K. 教授发给同时的 “LO”
    # 1971 美国国防部自主的阿帕网(Arpanet)的通讯机制
    # 通讯地址里用"@" 
    # 1987年中国的第一份电子邮件  
    # "Across the Great Wall we can reach every corner in the world"

# 管理程序
    # Euroda使邮件普及 
    # Netscape,outlook,forxmail后来居上
    # Hotmal使用浏览器发送邮件i
# 参考资料
    # [官网](https://docs.python.org/3/library/email.mime.html)
    
## 邮件工作流程
# MUA(MailUserAgent)邮件用户代理
# MTA(MailTransferAgent)邮件传输代理
# MDA(MailDeliveryAgent)邮件投递代理
# [email protected], 老师,北京海淀
# [email protected], 学生,上海江岸区
# 流程
    1. MUA#>MTA, 邮件已经在服务器上了
    2. qq MTA#>.........#>sina MTA, 邮件在新浪的服务器上
    3. sina MTA#> sina MDA, 此时邮件已经在你的邮箱里了
    4. sina MDA #> MUA(Foxmail/Outlook), 邮件下载到本地电脑
   
# 编写程序
    # 发送:  MUA#>MTA with SMTP:SimpleMailTransferProtocal,包含MTA#>MTA
    # 接受:  MDA#>MUA with POP3 and IMAP:PostOfficeProtocal v3 and  InternetMessageAccessProtocal v4
    
# 准备工作
    # 注册邮箱(以qq邮箱为例)
    # 第三方邮箱需要特殊设置, 以qq邮箱为例
        # 进入设置中心
        # 取得授权码
        
# Python for mail
    # SMTP协议负责发送邮件
    # 使用smtplib模块发送邮件 
    # 1、使用email模块构建邮件
        # 纯文本邮件
        # 案例:

    # 导入相应的包
    import smtplib
    from email.mime.text import MIMEText
    # MIMEText三个主要参数
    # 1. 邮件内容
    # 2. MIME子类型,在此案例我们用plain表示text类型
    # 3. 邮件编码格式
    msg = MIMEText("Hello, i am beijing tulingxueyuan ", "plain", "utf-8")
    # 发件人的email地址
    from_addr = "[email protected]"
    # 此处密码是经过申请设置后的授权码,不是不是不是你的qq邮箱密码
    from_pwd = "hjpovygcxmrshhcj"
    # 收件人信息
    to_addr = "[email protected]"
    # 输入SMTP服务器地址
    # 腾讯qq邮箱所的smtp地址是 smtp.qq.com
    smtp_srv = "smtp.qq.com"
    try:
            # 加密传输
        # 第一个是服务器地址,但一定是bytes格式,所以需要编码
        # 第二个参数是服务器的接受访问端口
        # srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465) #SMTP协议默认端口25
        # qq邮箱要求使用 TLS加密传输
        server = smtplib.SMTP(smtp_srv.encode(), 25) # SMTP协议默认端口是25
            server.starttls()
            # 设置调试级别
            # 通过设置调试等级,可以清楚的看到发送邮件的交互步骤
            server.set_debuglevel(1)
        #登录邮箱发送
        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格式邮件发送
      # 准备HTML代码作为内容
      # 把邮件的subtpye设为html
      # 发送
      # 案例片段,其他与TEXT发送一样:
    mail_content = """
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <h1> 这是一封HTML格式邮件</h1>
      </body>
      </html>

猜你喜欢

转载自blog.csdn.net/maopc1987/article/details/85682352
今日推荐