爬虫基础-计算机网络协议

news2024/11/19 23:17:07

一个数据的传输
image.png
这些设备的数据转发是通过协议来完成的,整个互联网可以说是完全由网络协议来维持的
不同的协议分工不同,比如ip协议确保了ip寻址,tcp协议确保了数据完整性

IP地址和URL

ip地址
整个网络传输可以比作快递,数据就是快递包裹
ip地址就是门牌号
URL
url(uniform resource locator)- 统一资源定位符,每一个url指向一个独特的资源,可以是一个html页面、一个css文档、一个图片、文件、js文件等
URL协议
image.png
常用协议:http、https、file、ftp
域名:可以看做说ip地址的别名,此次也可以直接填写ip地址

七层网络协议

image.png
image.png
image.png

TCP/IP协议

TCP协议
Tcp(传输控制协议)是一种面向连接、可可靠的基于字节流的传输层协议
理解:
tcp协议负责把需要传输的数据分解成一定长度的“片段”。
IP协议
Ip协议用于将多个数据包交换网络连接起来,它在源地址和目的地址之间传输数据包
理解
ip协议负责将数据“片段”贴上标签,成为数据包,标签包括“源ip地址”和“目标ip地址”。这些标签将决定数据传输的路径。Ip协议负责传送的道路被称为“路由功能”
路由器
路由器,是连接互联网各局域网、广域网的设备,他会根据信道的情况自动选择和设置路由,以最佳路径,按前后顺序发送数据
理解:
每个节点上的路由器都记录着与自己相邻的路由器地址,并形成一个表格-路由表,路由表是一个动态数据库,并在网络活动中不断更新。
数据包达到一个路由器后,该路由器会根据数据包的地址信息,查询路由表,然后选择一个最佳的路径发送数据包。

TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如ip地址、端口号等。
TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。
TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用4次挥手来关闭一个连接。

Socket

Socket可以用英文概念理解:插座
电力公司给你家送电是通过电线,但是电送到你家还不够,家里还得有个插座(socket),这样你才能用上电,插座上有火线、地线和中线。 可以理解为ip地址/端口等。
Socket本身并不是一个协议,是一个套接字,操作系统为了方便大家直接使用tcp协议而存在的一个抽象层,它把复杂的tcp/ip协议隐藏在接口后面。
image.png
image.png
socket_server

#socket服务端
import socket
import threading
server = socket.socket()
#绑定到0.0.0.0:8000端口上
server.bind(('0.0.0.0', 8000))
server.listen()

def handle_sock(sock, addr):
    while True:
        # recv方法是阻塞的
        tmp_data = sock.recv(1024)
        print(tmp_data.decode("utf8"))
        input_data = input()
        sock.send(input_data.encode("utf8"))

#获取客户端连接并启动线程去处理
while True:
    # 阻塞等待连接
    sock, addr = server.accept()

    #启动一个线程去处理新的用户连接
    client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
    client_thread.start()


#体验到直接获取原始数据,裸数据




    # if tmp_data:
    #     data += tmp_data.decode("utf8")
    #     if tmp_data.decode("utf8").endswith("#"):
    #         break
    # else:
    #     break;

# print(data)
# sock.close()

socket_client

#socket客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8000))

# client.send(b"bobby")
#当输出完成以后 以#结尾就代码提交完成
# server_data = client.recv(1024)
# print("server response: {}".format(server_data.decode("utf8")))
while True:
    input_data = input()
    client.send(input_data.encode("utf8"))
    server_data = client.recv(1024)
    print("server response: {}".format(server_data.decode("utf8")))

# client.close()

模拟qq服务器和客户端
server

#qq服务器
#1. 转发消息
#2. 处理登录
#3. 处理退出
#4. 维护历史消息, 维护在线用户和维护用户的连接
import socket
import json
from collections import defaultdict
import threading

#1. 维护用户连接
online_users = defaultdict(dict)

#2. 维护用户的历史消息
user_msgs = defaultdict(list)

server = socket.socket()

#绑定ip
server.bind(("0.0.0.0", 8000))
server.listen()

def handle_sock(sock, addr):
    while True:
        data = sock.recv(1024)
        json_data = json.loads(data.decode("utf8"))
        action = json_data.get("action", "")
        if action == "login":
            online_users[json_data["user"]] = sock
            sock.send("登录成功!".encode("utf8"))
        elif action == "list_user":
            #获取当前在线用户
            all_users = [user for user, sock in online_users.items()]
            sock.send(json.dumps(all_users).encode("utf8"))
        elif action == "history_msg":
            sock.send(json.dumps(user_msgs.get(json_data["user"], [])).encode("utf8"))
        elif action == "send_msg":
            if json_data["to"] in online_users:
                online_users[json_data["to"]].send(json.dumps(json_data).encode("utf8"))
            user_msgs[json_data["to"]].append(json_data)
        elif action == "exit":
            del online_users[json_data["user"]]
            sock.send("退出成功!".encode("utf8"))

while True:
    #阻塞等待连接
    sock, addr = server.accept()
    #启动一个线程去处理新的用户连接
    client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
    client_thread.start()

#1. 多线程去处理每个用户连接,防止主线程阻塞住
#2. 自定义了消息协议并且自己完成了消息协议的解析

client

#qq客户端
import socket
import json
import threading

client = socket.socket()
client.connect(("127.0.0.1", 8000))

user = "bobby1"

#1. 登录
login_template = {
    "action":"login",
    "user":user
}
client.send(json.dumps(login_template).encode("utf8"))
res = client.recv(1024)
print(res.decode("utf8"))

#2. 获取在线用户
get_user_template = {
    "action":"list_user"
}
client.send(json.dumps(get_user_template).encode("utf8"))
res = client.recv(1024)
print("当前在线用户:{}".format(res.decode("utf8")))

#2. 获取历史消息
offline_msg_template = {
    "action":"history_msg",
    "user":user
}
client.send(json.dumps(offline_msg_template).encode("utf8"))
res = client.recv(1024)
print("历史消息:{}".format(res.decode("utf8")))

exit = False
def hanle_receive():
    #处理接收请求
    while True:
        if not exit:
            try:
                res = client.recv(1024)
            except:
                break
            res = res.decode("utf8")
            try:
                res_json = json.loads(res)
                msg = res_json["data"]
                from_user = res_json["from"]
                print("")
                print("收到来自({})的消息: {}".format(from_user, msg))
            except:
                print("")
                print(res)
        else:
            break

def handle_send():
    while True:
        #1. 随时可以发送消息
        #2. 有新消息随时能接收到
        op_type = input("请输入你要进行的操作: 1. 发送消息, 2. 退出, 3. 获取在线用户")
        if op_type not in ["1","2","3"]:
            print("不支持该操作!!!")
            op_type = input("请输入你要进行的操作: 1. 发送消息, 2. 退出, 3. 获取在线用户")
        elif op_type == "1":
            to_user = input("请输入你要发送的用户:")
            msg = input("请输入你要发送的消息")
            send_data_template = {
                "action": "send_msg",
                "to": to_user,
                "from": user,
                "data": msg
            }
            client.send(json.dumps(send_data_template).encode("utf8"))
        elif op_type == "2":
            exit_template = {
                "action": "exit",
                "user": user
            }
            client.send(json.dumps(exit_template).encode("utf8"))
            exit = True
            client.close()
            break
        elif op_type == "3":
            get_user_template = {
                "action": "list_user"
            }
            client.send(json.dumps(get_user_template).encode("utf8"))

if __name__ == "__main__":
    send_thread = threading.Thread(target=handle_send)
    receive_thread = threading.Thread(target=hanle_receive)
    send_thread.start()
    receive_thread.start()





#qq客户端
import socket
import json
import threading

client = socket.socket()
client.connect(("127.0.0.1", 8000))

user = "bobby2"

#1. 登录
login_template = {
    "action":"login",
    "user":user
}
client.send(json.dumps(login_template).encode("utf8"))
res = client.recv(1024)
print(res.decode("utf8"))

#2. 获取在线用户
get_user_template = {
    "action":"list_user"
}
client.send(json.dumps(get_user_template).encode("utf8"))
res = client.recv(1024)
print("当前在线用户:{}".format(res.decode("utf8")))

#2. 获取历史消息
offline_msg_template = {
    "action":"history_msg",
    "user":user
}
client.send(json.dumps(offline_msg_template).encode("utf8"))
res = client.recv(1024)
print("历史消息:{}".format(res.decode("utf8")))

exit = False
def hanle_receive():
    #处理接收请求
    while True:
        if not exit:
            try:
                res = client.recv(1024)
            except:
                break
            res = res.decode("utf8")
            try:
                res_json = json.loads(res)
                msg = res_json["data"]
                from_user = res_json["from"]
                print("")
                print("收到来自({})的消息: {}".format(from_user, msg))
            except:
                print("")
                print(res)
        else:
            break

def handle_send():
    while True:
        #1. 随时可以发送消息
        #2. 有新消息随时能接收到
        op_type = input("请输入你要进行的操作: 1. 发送消息, 2. 退出, 3. 获取在线用户")
        if op_type not in ["1","2","3"]:
            print("不支持该操作!!!")
            op_type = input("请输入你要进行的操作: 1. 发送消息, 2. 退出, 3. 获取在线用户")
        elif op_type == "1":
            to_user = input("请输入你要发送的用户:")
            msg = input("请输入你要发送的消息")
            send_data_template = {
                "action": "send_msg",
                "to": to_user,
                "from": user,
                "data": msg
            }
            client.send(json.dumps(send_data_template).encode("utf8"))
        elif op_type == "2":
            exit_template = {
                "action": "exit",
                "user": user
            }
            client.send(json.dumps(exit_template).encode("utf8"))
            exit = True
            client.close()
            break
        elif op_type == "3":
            get_user_template = {
                "action": "list_user"
            }
            client.send(json.dumps(get_user_template).encode("utf8"))

if __name__ == "__main__":
    send_thread = threading.Thread(target=handle_send)
    receive_thread = threading.Thread(target=hanle_receive)
    send_thread.start()
    receive_thread.start()





http协议

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC。http是应用层协议。
HTTP协议永远都是客户端发起请求,服务器回送响应,这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。HTTP协议是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。http协议是单向的。
HTTP 协议是个纯文本的协议,:这意味着我们直接传递纯文本就可以了换句话说,一个 Web 服务器其实就是根据约定好的方法生成对应的 HTTP 消息内容然后传输给对方。

http协议格式

简单快速:只需要传递请求方法和路径。
灵活:http可以传递任意类型的数据对象。通过content-type指定
无连接:无连接意味着每次连接处理一个请求,服务器返回之后断开连接,节省传输时间和服务器压力。
无状态:无状态是指协议对于事物处理没有记忆能力,需要通过cookie和session来加以区别。
支持B/S和C/S模式
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C51 单片机学习(一):基础外设

参考 51单片机入门教程 1. 单片机简介 1.1 定义 单片机(Micro Controller Unit,简称 MCU) 内部集成了 CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能单片机的任务是信息采集(依靠传感器)、处…

【Spark系列2】Spark编程模型RDD

RDD概述 RDD最初的概述来源于一片论文-伯克利实验室的Resilient Distributed Datasets:A Fault-Tolerant Abstraction for In-Memory Cluster Computing。这篇论文奠定了RDD基本功能的思想 RDD实际为Resilient Distribution Datasets的简称,意为弹性分…

Linux提权:Docker组挂载 Rsync未授权 Sudo-CVE Polkit-CVE

目录 Rsync未授权访问 docker组挂载 Sudo-CVE漏洞 Polkit-CVE漏洞 这里的提权手法是需要有一个普通用户的权限,一般情况下取得的webshell权限可能不够 Rsync未授权访问 Rsync是linux下一款数据备份工具,默认开启873端口 https://vulhub.org/#/envir…

Linux:共享内存

文章目录 System V共享内存的原理管理共享内存shmgetshmatshmdtshmctl 共享内存和管道实现进程间同步通信 前面介绍完了匿名管道和命名管道,那么本篇要引入的主题是共享内存 System V 作为进程通信部分的内容,共享内存必然有其存在的意义和价值&#x…

RabbitMQ快速实战

目录 什么是消息队列? 消息队列的优势 应用解耦 异步提速 削峰填谷 总结 主流MQ产品特点比较 Rabbitmq快速上手 创建用户admin Exchange和Queue Connection和Channel RabbitMQ中的核心概念总结 什么是消息队列? MQ全称Message Queue&#xf…

从零学习Linux操作系统 第二十二部分 企业域名解析服务的部署及安全优化

# 一、dns的主要信息 关于dns的名词解释:dns: domain name service(域名解析服务) 关于客户端: /etc/resolv.conf dns指向文件 A记录 ##ip地址叫做域名的Address 记录 SOA ##授权起始主机 关于服务端 bind安装包named服务名称/etc/named.conf主配置文件/var/na…

【深度学习:多关节嵌入模型】 Meta 解释的 ImageBind 多关节嵌入模型

【深度学习:多关节嵌入模型】 Meta 解释的 ImageBind 多关节嵌入模型 Meta 发布开源人工智能工具的历史分段任何模型DINOv2 什么是多模态学习?什么是嵌入?什么是 ImageBind?集成在 ImageBind 中的模式图像绑定架构特定模式编码器跨…

window下如何安装ffmpeg(跨平台多媒体处理工具)

ffmpeg是什么? FFmpeg是一个开源的跨平台多媒体处理工具,可以用于录制、转换和流媒体处理音视频。它包含了几个核心库和工具,可以在命令行下执行各种音视频处理操作,如剪辑、分割、合并、媒体格式转换、编解码、流媒体传输等。FFmpeg支持多…

java设计模式:工厂模式

1:在平常的开发工作中,我们可能会用到不同的设计模式,合理的使用设计模式,可以提高开发效率,提高代码质量,提高系统的可拓展性,今天来简单聊聊工厂模式。 2:工厂模式是一种创建对象的…

Java TemporalAdjusters 时间调节器

提供了非常多处理日期相关的函数: 使用示例: /*** JCccc* param args*/public static void main(String[] args) {DateTimeFormatter pattern DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDateTime now LocalDateTime.now();//获取当月…

备战蓝桥杯---二分(入门)

话不多说,先来个模板题来回顾一下上次讲的: 下面是AC代码: 下面进入正题: 本题对1,2行与3,4行组合,再用二分查找即可实现n^2logn的复杂度。 下面是AC代码: 接题: 让我们…

基于springboot校园交友网站源码和论文

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&#xf…

QT学习日记 | QT的环境搭建

目录 前言 一、QT概述 二、QT的环境搭建 1、QT SDK安装 2、环境变量的配置 前言 本系列为小编新开的一个系列,主要记录小编学习QT的过程,作为笔记仅供各位参考; 一、QT概述 Qt是一个跨平台C图形应用界面框架;简单来说&#x…

Android 13.0 SystemUI下拉状态栏定制二 锁屏页面横竖屏时钟都居中功能实现二

1.前言 在13.0的系统rom定制化开发中,在关于systemui的锁屏页面功能定制中,由于在平板横屏锁屏功能中,时钟显示的很大,并且是在左旁边居中显示的, 由于需要和竖屏显示一样,所以就需要用到小时钟显示,然后同样需要居中,所以就来分析下相关的源码,来实现具体的功能 如图…

C++:异常体系

异常体系 异常1.C语言传统的处理错误的方式2.C异常概念3.异常的使用3.1异常的抛出和捕获3.2 异常的重新抛出3.3异常安全3.4 异常规范 4.C标准库的异常体系5.异常的优缺点 异常 1.C语言传统的处理错误的方式 终止程序,如assert,缺陷:用户难以…

鸿蒙 ArkTs初识

前提:基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。(或有偏颇,自行斟酌) 吐槽:官网上的案例只有代码和文档解释,没有可以直接运行查看效果的模拟器,这一点上&#…

Qt|大小端数据转换

后面打算写Qt关于网络编程的博客,网络编程就绕不开字节流数据传输,字节流数据的传输一般是根据协议来定义对应的报文该如何组包,那这就必然牵扯到了大端字节序和小端字节序的问题了。不清楚的大小端的可以看一下相关资料:大小端模…

【RTP】webrtc 学习3: webrtc对h264的rtp解包

rtp_rtcp\source\video_rtp_depacketizer_h264.cc【RTP】webrtc 学习2: webrtc对h264的rtp打包 中分析了打包过程的代码,这样再来看解析过程的源码就容易多了:本代码主要基于m79,m98类似。这里注明了jitterbuffer 会再次 做 解析stap-a 变为NAL units解析ParseFuaNalu 第一…

Jmeter 分布式测试

Jmeter单机进行压测,受到单台机器的性能影响,Jmeter支持分布式测试,用一个控制节点去控制多个工作节点去模拟更多的用户。 版本信息 内容版本号JDK1.8Jmeter5.6.2 分布式测试原理 jmeter 官网对分布式测试有说明,jmeter分布式…

RabbitMQ 死信交换机的详述➕应用

🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于RabbitMQ的相关操作吧 目录 🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 一.什么是死信交换机 二. 死信队列…