网络编程

网络编程

  • 网络
  • 网络协议:一套规则
  • 网络模型:
    • 七层模型
      • 物理层
      • 数据链路层
      • 网络层
      • 传输层
      • 会话层
      • 表示层
      • 应用层
    • 四层模型-------实际应用
      • 链路层
      • 网络
      • 传输层
      • 应用层
  • 每一层都有相应的协议负责交换信息或者协同工作
  • 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)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容