# 网络协议与应用

# HTTP协议

from time import time
from threading import Thread

import requests

class DownloadHandler(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('imgs/'+ filename,'wb') as f:
            f.write(resp.content)


def main():
    resp = requests.get('https://www.mxnzp.com/api/image/girl/list?page=1&app_id=&app_secret=')
    data = resp.json()
    img_list = data['data']

    for img in img_list:
        url = img['imageUrl']
        DownloadHandler(url).start()


if __name__ == '__main__':
    main()

# TCP套接字

在Python中也可以基于套接字来使用传输层提供的传输服务,并基于此开发自己的网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字(UDP套接字)和原始套接字

"""
    基于TCP套接字创建一个时间日期的服务器
"""
from socket import socket,SOCK_STREAM,AF_INET
from datetime import datetime

def main():
    # 创建套接字对象并制定使用哪种传输服务
    # family=AF_INET - IPv4地址
    # family=AF_INET6 - IPv6地址
    # type=SOCK_STREAM - TCP套接字
    # type=SOCK_DGRAM - UDP套接字
    # type=SOCK_RAW - 原始套接字
    server = socket(family=AF_INET,type=SOCK_STREAM)
    # 绑定IP地址和端口,同一时间,在同一个端口上只能绑定一个服务
    server.bind(('192.168.2.115',6789))
    # 开启监听 
    server.listen(512)
    print('服务器启动,开始监听。。。')
    while True:
        # 通过循环,接收客户端的连接并做出相应的处理
        # accept 是一个阻塞方法,如果没有客户端连接到服务器,代码不会向下执行
        client,addr = server.accept()
        print(str(addr) + '连接到了服务器')

        # 发送数据
        client.send(str(datetime.now()).encode('utf-8'))
        # 断开连接
        client.close()

if __name__ == '__main__':
    main()

上面创建了服务器,那么下面就是建立了客户端

"""
    创建一个客户端
"""

from socket import socket

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

TCP套接字的使用需要以下步骤:

  • 创建套接字:在客户端和服务器端,应用程序首先创建一个套接字对象。

  • 绑定地址和端口:在服务器端,套接字需要绑定到一个特定的IP地址和端口号上,以便客户端能够连接到它。

  • 监听连接请求(仅服务器端):服务器端的套接字开始监听来自客户端的连接请求。

  • 建立连接:三次握手(只是用户建立和确认连接)

第一次:发起连接

客户端向服务端请求建立连接,发送一个SYN(同步)数据包,进入SYN_SENT(同步已发送)状态,等到服务器的确认。

第二次:确认连接请求,发送连接请求

服务器确认连接请求,回复给客户端一个ACK(确认)数据包,同时也会发送一个SYN数据包给客户端,服务器已进入SYN_RECV(同步已接收)状态,等待客户端的确认。

第三次:完成连接

客户端手段服务器的ACK+SYN数据包后,会向服务器发送一个ACK数据包进行确认。表示客户端已经准备好就收数据了。

简单理解一下:首先客户端告诉服务器,我已经发数据给你了,你收到了吗?,客户端收到数据之后,告诉客户端,我收到了,我已经准备好接收数据了,客户端说好嘞,那我发了。

在三次握手过程中,每次发送的数据包都不包含实际的数据内容,只是用于建立和确认连接。当三次握手完成后,客户端和服务器就可以开始传输实际的数据了。

  • 数据传输:连接建立后,客户端和服务器就可以通过套接字发送和接收数据了。

  • 关闭连接:数据传输完成后,客户端和服务器都会关闭套接字以释放资源。关闭连接的过程通常包括四次挥手。

# UDP套接字

传输层除了有可靠的传输协议TCP之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称UDP。TCP和UDP都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP可能是更好的选择。可能大家会注意到一个现象,就是在观看网络视频时,有时会出现卡顿,有时会出现花屏,这无非就是部分数据传丢或传错造成的。

# 网络应用开发

发送短信,发送电子邮件(基于SMTP简单邮件传输协议)