网络编程

准备知识

  • 网络通信的七层:
    1. 物理层:例如光纤之类(相当于快递公司)
    2. 数据链路层:例如局域网的实现(相当于从北京海淀顺丰与北京朝阳顺丰之间的连接)
    3. 网络层:IP之类,如何在网络中寻找特定的计算机层面(从北京顺丰到上海顺丰之间)
    4. 传输层:TCP,传递数据时,应该遵循的特定解析规则(传递的快件应该怎么进行包装)
    5. 会话层 :scoket创建套接字,标识已经创建该通信通道(寄送快递)
    6. 表示层 :接受到的信息该怎么解析给本机器进行使用(相当于拆快递)
    7. 应用层:http(拿到快件,比如灯泡,这个灯泡开始为我服务)
  • 网络协议(TCP/IP) : 当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。
  • 端口:接受到数据后,该把这个数据发送给什么程序应用,程序从这个地方接受我需要的数据

TCP/UDP服务器端通信方法

  • 创建流程:
    1. 建立socket,socket是负责具体通信的一个实例
    2. 绑定,为创建的socket指派固定的端口和ip地址
    3. 在tcp传输时,需要监听通道listen
    4. 在tcp传输前,需要接受连接请求
    5. 接受对方发送内容
    6. 给对方发送反馈,此步骤为非必须步骤
  • UDP代码实现:
# 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)

    print(data)
    print(type(data))

    # 发送过来的数据是bytes格式,必须通过解码才能得到str格式内容
    # decode默认参数是utf8
    text = data.decode()
    print(type(text))
    print(text)


    # 给对方返回的消息
    rsp = "Ich hab keine Hunge"

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


if __name__ == '__main__':
    print("Starting server.........")
    serverFunc()
    print("Ending server........")
  • 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.......")
  • 服务器工作:
    1. 服务器接受请求时,从通信端口接收,然后接受到的信息返回为一个元组,第一项为,请求类型,第二项为来源地址(IP+PORT),以便,传输数据时候能够返回给对应的客户端
    2. 通信时,信息的传递时bytes的格式,所以,服务器接收到信息后需要对数据进行decode,同理,传出数据时也需要对数据进行encode
    3. 服务器一般选择使用死循环,让服务器一直运行下去
    4. TCP是建立连接后,接收到请求后,在进行连接数据通道,可理解为,服务器监听客户的请求信号,得到信号后,开启传输数据的通道,在完成数据传输后,关闭数据通道,但保留信号通道,所以有以下代码
      scok.listen()		#负责监听请求信号
      sock.accept()		#负责接受传递的数据
      
      可以区分UDP和TCP之间的区别,UDP直接传输文件,而TCP是先与客户端进行通信,确认有文件会传输过来,如果TCP的服务器没有连接,那么客户端就不发送消息,而是请求通道,但是UDP会直接发送文件,所以导致数据可能丢失。

TCP/UDP客户端通信方法

  • 通信流程:
    1. 建立通信(告诉机器,我需要传递消息,需要分配一个端口)
    2. 向服务器发送请求
    3. TCP客户端链接对方
    4. TCP发送或接受文件
    5. 接受服务器返回内容
  • 代码实现:
import socket


def clientFunc():

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


    text = "I love jingjing"

    # 发送的数据必须是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()

  • TCP客户端
import socket


def clientFunc():

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.connect('127.0.0.1', 7852)
    text = "I love jingjing"

    # 发送的数据必须是bytes格式
    data = text.encode()

    # 发送
    sock.send(data)
    data = sock.recv(200)
    data = data.decode()

    print(data)
    sock.close()


if __name__ == '__main__':
    clientFunc()

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上某一个文件,需要上述三部分组合在一起
  • 代码实现:

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编程

  • 邮件传输流程:
    1. MUA:MailUserAgent
    2. MTA:MailTransferAgent
    3. MDA:MailDeliverAgent
  • 代码实现:
    1. 发送: MUA->MTA
      SMTP:SimpleMailTransferProtocal
    2. 接收: MDA->MUA IMTP:
      ostOfficeProtocal v3
      InternetMessageAccessProtocal v4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值