[Python-14/100] 网络编程入门-A(Introduction to Network Programming)

版权声明:公众号:Fresh Site。QQ群:690274159。转载我的博文时,请附上转载地址,谢谢!^_^我是嘻哈程序猿freshman。 https://blog.csdn.net/wuhongxia29/article/details/90767708

参考资料:
github-100 可以参考该项目的计划安排,具体每天的知识详情不是很全面,可以自己再扩展(可结合廖雪峰的网站学习)。据了解该项目的初始作者不是目前的负责人,现在的负责人是一名培训机构的老师。根据我学习该项目的这段时间,我感觉项目的质量跟星数不是很匹配,国际知名的开源项目pytorch等也才两万多星,该项目就有三万多星,该项目的星数不免有刷星的嫌疑,我再观察了一下点星的用户信息,大多都是新用户,或者很少用github的人,有可能是该培训机构的学员刷星也有可能。
廖雪峰-网络编程
OSI七层


网络基础

七层模型(OSI/RM)

在这里插入图片描述
OSI七层

四层模型(TCP/IP)

TCP/IP vs OSI/RM

三次挥手与四次握手

参考资料:TCP协议

三次握手

通俗说法:淘宝卖家(客户端)与买家(服务器)的故事

  • 第一次:卖家在“旺旺”上对买家发消息说“我想卖东西给你”
  • 第二次:买家收到买家消息,发送消息说“好的,你发货过来吧。”
  • 第三次:卖家收到买家消息,发送消息说“包裹发过来了。”
    在这里插入图片描述

四次挥手

  • 请求方可以是客户端或者买家,都可以请求关闭
  • 卖家(请求方:客户端)和买家(服务器)
  • 第一次:卖家发送消息,“你不会freestyle,东西我不卖你了,交易我要关闭了”(傲娇的卖家)
  • 第二次:买家收到消息,发送消息,“卧槽,你真拽,我心脏受不了,你给我点时间准备一下。”
  • 第三次:过了一段时间,买家发送消息,“速效救心丸吃完了,我准备好了。”
  • 第四次:卖家收到消息,发送消息,“关闭交易,再见。哼!”
    在这里插入图片描述

网络应用模式

1.C/S和B/S

  • Client-Server
  • Browser-Server

2.去中心化网络应用模式

无固定的服务器和客户端,应用使用者也可以是资源提供者和访问者


基于HTTP协议(应用层)的资源访问

在这里插入图片描述

HTTP

HTTP(Hyper-Text Transfer Proctol):超文本传输协议,获取网络资源,API。

JSON格式

JSON(JavaScript Object Notation)(js对象符号)

{
    "from": "Alice",
    "to": "Bob",
    "content": "Will you marry me?"
}

requests

例子:

from time import time
from threading import Thread

import requests


# 继承Thread类创建自定义的线程类
class DownloadHanlder(Thread):

    def __init__(self, url):
        super().__init__()
        self.url = url

    def run(self):
        filename = self.url[self.url.rfind('/') + 1:]
        resp = requests.get(self.url)
        with open('/Users/Hao/' + filename, 'wb') as f:
            f.write(resp.content)


def main():
    # 通过requests模块的get函数获取网络资源
    # 下面的代码中使用了天行数据接口提供的网络API
    # 要使用该数据接口需要在天行数据的网站上注册
    # 然后用自己的Key替换掉下面代码的中APIKey即可
    resp = requests.get(
        'http://api.tianapi.com/meinv/?key=APIKey&num=10')
    # 将服务器返回的JSON格式的数据解析为字典
    data_model = resp.json()
    for mm_dict in data_model['newslist']:
        url = mm_dict['picUrl']
        # 通过多线程的方式实现图片下载
        DownloadHanlder(url).start()


if __name__ == '__main__':
    main()

基于传输层协议的套接字编程

在这里插入图片描述
定义:C语言,应用程序开发库,进程通信、网络编程。
分类:

扫描二维码关注公众号,回复: 6408091 查看本文章
  • 流套接字(TCP套接字)
  • 数据报套接字
  • 原始套接字

TCP套接字

定义:TCP协议,编程接口。

端口:0~65535(著名端口<1024 )
family: AF_INET - IPv4地址, AF_INET6 - IPv6地址
type: SOCK_STREAM - TCP套接字, SOCK_DGRAM - UDP套接字,SOCK_RAW - 原始套接字

例1:时间日期服务器、客户端

# 时间日期服务器
from socket import socket, SOCK_STREAM, AF_INET
from datetime import datetime


def main():
    # 1.创建套接字对象并指定使用种传输服务
    # (family=AF_INET - IPv4地址, AF_INET6 - IPv6地址) 
    # (type=SOCK_STREAM - TCP套接字, SOCK_DGRAM - UDP套接字,SOCK_RAW - 原始套接字)
    server = socket(family=AF_INET, type=SOCK_STREAM)

    # 2.绑定IP地址和端口(端口用于区分不同的服务)(同一时间在同一端口上只能绑定一个服务否则报错)
    server.bind(('10.0.0.18', 6789))

    # 3.开启监听 - 监听客户端连接服务器 # 参数512可以理解为连接队列的大小
    server.listen(512)
    print('服务器启动开始监听。。。')

    while True:
        # 4.通过循环接收客户端的连接并作出相应的处理(提供服务)
        client, addr = server.accept()  # acccept是阻塞方法,返回元组(第一个元素客户端对象)
        print(str(addr) + '连接到了服务器')

        # 5.发送数据
        client.send(str(datetime.now()).encode('utf-8'))

        # 6.断开连接
        client.close()


if __name__ == '__main__':
    main()
# 时间日期客户端
from socket import socket


def main():
    # 1.创建套接字对象默认使用IPv4和TCP协议
    client = socket()
    # 2.连接到服务器(指定IP和端口)
    client.connect(('10.0.0.18', 6789))
    # 3.从服务器接收数据
    print(client.recv(1024).decode('utf-8'))
    client.close()


if __name__ == '__main__':
    main()

例2:图片服务器、客户端

# 图片服务器
from socket import socket, SOCK_STREAM, AF_INET  # TCP套接字,IPv4
from base64 import b64encode
from json import dumps
from threading import Thread


def main():

    # 自定义线程类
    class FileTransferHandler(Thread):

        def __init__(self, cclient):
            super().__init__()
            self.cclient = cclient

        def run(self):
            my_dict = {}
            my_dict['filename'] = 'guido.jpg'
            my_dict['filedata'] = data  # JSON是纯文本不能携带二进制数据,所以图片要处理为base64编码
            json_str = dumps(my_dict)  # 通过dumps函数将字典处理成JSON字符串
            self.cclient.send(json_str.encode('utf-8'))  # 发送JSON字符串
            self.cclient.close()

    # 1.创建套接字对象并指定使用哪种传输服务
    server = socket()
    # 2.绑定IP和端口
    server.bind(('10.0.0.18', 5566))
    # 3.开启监听
    server.listen(512)  # 参数512可以理解为连接队列的大小
    print('服务器启动开始监听。。。')
    with open('guido.jpg', 'rb') as f:
        data = b64encode(f.read()).decode('utf-8')  # 将二进制数据处理成base64再解码成字符串
    while True:
        client, addr = server.accept()
        FileTransferHandler(client).start()

if __name__ == '__main__':
    main()
# 图片客户端
from socket import socket
from json import loads
from base64 import b64decode


def main():
    client = socket()
    client.connect(('10.0.0.18', 5566))
    in_data = bytes()  # 定义一个保存二进制数据的对象
    data = client.recv(1024)  # 由于不知道服务器发送的数据有多大每次接受1024字节
    while data:
        in_data += data  # 将收到的数据拼接起来
        data = client.recv(1024)
    # 将收到的二进制数据解码成JSON字符串并转换成字典
    my_dict = loads(in_data.decode('utf-8'))  # loads函数的作用就是将JSON字符串转成字典对象
    filename = my_dict['filename']
    filedata = my_dict['filedata'].encode('utf-8')
    with open('' + filename, 'wb') as f:
        f.write(b64decode(filedata))  # 将base64格式的数据解码成二进制数据并写入文件
    print('图片已保存')


if __name__ == '__main__':
    main()

UDP套接字

轻便,稳定性较差

猜你喜欢

转载自blog.csdn.net/wuhongxia29/article/details/90767708