网络基本概念初识

1. 一些协议的相关概念

协议是网络协议的简称;

网络协议是通信计算机双方必须共同遵从的一组约定。

如怎么样建立连接,怎么样互相识别等。

只有遵守这个约定,计算机之间才能互相通信交流

协议三要素:

语法、语义、时序

协议族/簇/组:

协议族/簇/组:多个相关协议的组合

常见的传输层协议有:TCP、UDP

2. socket

Socket是一种网络通信协议,它提供了一种在网络上进行数据传输的方式。

Socket可以在不同的计算机之间建立连接,使得它们之间可以互相传输数据。

Socket通常用于编写网络应用程序,如聊天室、在线游戏、文件传输等。

Socket通信是基于客户端-服务器模型的,其中客户端向服务器发送请求,服务器接收请求并响应客户端。

Socket通信使用TCP或UDP协议进行数据传输。

TCP协议提供了可靠的数据传输,确保数据的正确性和完整性,但是传输速度较慢;

而UDP协议则提供了快速的数据传输,但是不保证数据的正确性和完整性。

网络三要素:

IP,PORT,协议

本地socket实例:

在所有语言中,都有封装好的socket方法,我们在进行网络编程时,可以直接调用

下面是一个python的socket实例:

由于是在本地进行C/S(serve/client,即服务端向客户端)效果演示,需要新建2个py文件

先新建一个服务端 server.py文件,由于目前还没有程序来进行访问,执行后会一直卡着,如下:

import socket

sock = socket.socket()
sock.bind(("xxx.xx.xx.x",8890))  #输入ip和端口号
sock.listen(5)

#等待客户端链接
print("server is waiting……")
conn,addr = sock.accept()    #等待客户端来链接
print("conn",conn)
print("addr",addr)

conn.send(b"HTTP/1.1 200 ok\r\n\r\nhello world!") #发送符合http格式的字符串信息
data = conn.recv(1024)  #接收符合格式的客户端内容,最大1024
print("data:",data)

#输出:由于还没有客户端发起访问,所以一直显示:
server is waiting……

再新建一个客户端client.py文件,先执行上面的py文件

再执行如下的py文件,第二个py文件执行完不会有任何输出

import socket

sock = socket.socket()
sock.connect(("xxx.xx.xx.x.x",端口号)) #这里的ip和端口号需要与服务端一致


#向服务端发送一条消息:
sock.send(b"hello world!")

再看第一个py文件的控制台,会显示已链接成功及链接信息、接收到的客户端信息:

data返回:hello world!

同样,服务端启动后,也可以向客户端发送消息

本地模拟socket--b/s程序:

b/s(Browser/Server):指的浏览器和服务器架构模式

在这种架构下,客户端通过WWW浏览器来实现与服务器的链接

浏览器发起访问请求后,服务端返回对应的数据

如下,简单模拟一个京东服务器的实例:

#本地模拟写一个京东服务器:
import socket

sock = socket.socket()
sock.bind(("xxx.xx.xx.x.x",8890))
sock.listen(3)
print("京东服务器已启动……")

while 1:
    conn,addr = sock.accept()   #等待客户端来链接
    print("data:",data)
    conn.send(b"HTTP/1.1 200 ok\r\n\r\nhello world!")   #发送符合http协议格式的字符串消息
    data = conn.recv(1024)  #接收符合格式的客户端内容,最大1024
    conn.close()

#运行后输出:
京东服务器已启动……

打开浏览器 -> 直接输入上述代码中的ip:端口号,浏览器端接收显示信息如下:

通信协议的固定格式:conn.send(b"HTTP/1.1 200 ok\r\n\r\nxxx……xx")

如果发送的内容,没有按照http的固定格式写,会发生什么情况呢?

#本地模拟写一个京东服务器:
import socket

sock = socket.socket()
sock.bind(("xxx.xx.xx.x.x",8890))
sock.listen(3)
print("京东服务器已启动……")

while 1:
    conn,addr = sock.accept()      #等待客户端来链接
    print("data:",data)
    conn.send(b"hello world!")     #发送不符合http协议格式的字符串消息,可以发送成功
    data = conn.recv(1024)
    conn.close()

#运行后输出:
京东服务器已启动……

重新打开浏览器 -> 直接输入上述代码中的ip:端口号,浏览器端接收显示信息如下:

这时候,服务端启动成功 -> 浏览器也拿到了服务返回的数据,但是由于它无法解析内容

所以如上截图,无法正常显示。

主要原因是,代码中没有遵循http协议的传输规则,导致服务端无法解析。

虽然作为爬虫来讲,我们不需要知道如何进行具体开发,但是我们需要知其所以然,

所以接下来,我们需要了解http网络协议的相关知识。


3. http网络协议

http协议简介:

http协议是超文本传输控制协议。

是一种按照URL指示,将超文本文档从一台主机(web服务器)传输到另一台主机(浏览器)的应用层协议,以实现超链接的功能。

http协议的特性:

http协议具有以下4个特性:

 (1) 基于TCP/IP协议
http协议是基于TCP/IP协议之上的应用层协议。


(2) 基于请求响应模式
BTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。


 (3)无状态保存
HTP是一种不保存状态,即无状态(stateless)协议。

HTTP协议自身不对请求和响应之间的通信状态进行保存。

也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化理。
使用BTTP协议,每当有新的请求发送时,就会有对应的新响应产生。

协议本身并不保留之前一切的请求或响应报文的信息。

这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单。


(4)短连接和长连接
HTTP1.0默认使用的是短连接。浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。

HTTP/1.1起,默认使用长连接。要使用长连接,客户端和服务器HTTP首部的Connection都要设置为keep-alive,才能支持长连接HTTP长连接,指的是复用TCP连接。

多个HTTP请求可以复用同一个TCP连接,这就节省了TCP连接建立和断开的消耗。

4. http协议--请求报文

htp协议包含:由浏览器发送数据到服务器需要遵循的请求协议、服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。

请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。

HTTP报文本身是由多行数据构成的字文本。

一个完整的URL包括:协议、ip、端口、路径、参数  

例如:

https://www.baidu.com/s?wd=yuan

其中https是协议

www.baidu.com 是IP

端口默认80

/s是路径

参数是wd=yuan

 请求报文方式汇总:

方法(操作)

含义

方法(操作)

含义

GET

请求读取一个web页面

HEAD

请求读取一个web页面的首部

POST

附加一个命名资源(如web页面)

PUT

请求存储一个web页面

DELETE

删除web页面

TRACE

用于测试,要求服务器送回收到的请求

CONNECT

用于代理服务器

OPTION

查询特定选项

常见--get请求&post请求:

● GET请求:

get提交的数据只会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456.

● POST请求:

post方法是把提交的数据放在HTTP包的请求体中。

格式如下:

请求首行

若干个请求头每个占一行 空一行

请求体数据

GET提交的数据大小有限制(因为浏览器对URL的长度有限制)

而POST方法提交的数据没有限制

首部字段/消息头含义

头(header)

类型

说明

User-Agent

请求

关于浏览器和它平台的信息,如Mozilla5.0

Accept

请求

客户能处理的页面的类型,如text/html

Accept-Charst

请求

客户可以接受的字符集,如Unicode-1-1

Accept-Encoding

请求

客户能处理的页面编码方法,如gzip

Host

请求

可能处理的DNS名称。从URL中提取出来,必需

Authorization

请求

客户的信息凭据列表

Cookie

请求

将以前设置的Cookie送回服务器,可用来作为会话信息

Date

双向

消息被发送时的日期和时间

Server

响应

关于服务器的信息,如Microsoft-lls/6.0

Content-Ecoding

响应

内容是如何被编码的(如gzip)

Content-Language

响应

页面所使用的自然语言

Content-Length

响应

以字节计算的页面长度

Content-Type

响应

页面的MIME类型(组装类型:x-mm-form表单、josn)

Last-Modified

响应

页面最后被修改的时间和日期,在页面缓存机制中意义重大

Location

响应

指示客户请求发送给别处,即重定向到另一个URL

Set-Cookie

响应

服务器希望客户报错一个Cookie

http请求示例

例如:请求 www.baidu.com

打开浏览器 -> 快捷键F12,或者右键检查--network

请求 www.baidu.com时的--请求头文件: 

基于postman完成请求测试

基于前面的socket代码,首先运行代码

ps:如果连续多次运行代码报错,就修改端口号

import socket

sock = socket.socket()
sock.bind(("xxx.xx.xx.x.x",8890))  #本地ip,端口号(可随意写4位数)
sock.listen(3)
print("京东服务器已启动……")

while 1:
    conn,addr = sock.accept()         #等待客户端链接
    print("data:",data)
    conn.send(b"hello back girl!")    #要发送的字符串消息
    data = conn.recv(1024)            #接收客服端的消息,最大长度1024
    conn.close()

将代码中的ip:端口号,直接输入到postman

- >如果是post请求:需要Body中填写key、value

- >如果是get请求:填写Params中填写key、value

如下截图为psot:

 然后点击send:Body中就会显示接收到的信息(代码中的send)

postman--点击send时,将上述截图的2个键值对,作为请求体传给服务器

以下是pycharm控制台输出中接收的请求信息,复制出来如下

可以看出是与正常浏览器进行访问时的请求内容相同:

POSTTP/.1

User-Agent: PostmanRuntime/7.29.2

Accept:*/*

Postman-Token: 07e336c1-5bc4-4759-b3db-fleeec0604d8

inHost:27.0.0.1:889

Accep-Encoding: gzip, deflate, brrinom

ection: keep-aliverlo

content-Type: application/x-mm-form-urlencodedrino

tent-Length:20\r\n\r\nuser=yuan&pwd=123456

postman中接收到服务器发送的信息

服务器中也接收到了postman发送请求的内容

至此,说明测试成功~

★组装格式tips:

以上述栗子,请求中的体中的key、value的组装格式通常有如下两种:

x-mm-formurlencodedrino(表单格式):user = yua&pwd=123456

josn格式:{"user":"yuan","pwd":"123456"}

进行请求的时候,上面任意一种组装格式都没问题

but:在请求头_content-Type中必须声明组装格式,不然服务器拿到的只是一个字符串,无法进行解析。

5. http响应格式

响应示例:

对上面的socket代码进行加工:

添加请求头信息:Content-Type:text/htm

让"hello world"变成一级标题:"hello world"放在<h1> </h1>中间

并且添加一张图片:百度找一张图片 -> 点击图片右键 -> 复制图片地址,进行添加

代码如下:

sock = socket.socket()
sock.bind(("xxx.xxx.x.xxx",8890))
sock.listen(3)
print("京东服务器已启动……")

while 1:
    conn,addr = sock.accept()
    data = conn.recv(1024)
    print("data:",data)
    conn.send ( b"HTTP/1.1 200 ok\r\ncontent-type:text/html\r\n\r\n<h1>hello world!</h1><img "
        b"src='https://img2.baidu.com/it/u=3413024138,1887722785&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'>")   #发送符合格式的字符串消息+消息设为一级标题+一张图片

    conn.close()

再次打开浏览器,输入ip:端口号

就显示出来了粗标题的"hello world",以及一张图片:

 

 开发者工具中,显示表头(响应头)的类型为代码中指定的text/htm类型:

text/htm表示发送请求后,传到服务端,需要进行前端渲染,即显示出我们想要的样式

如果Content-Type,写为text/plain,即不会进行任何渲染,展示为纯字节文本


响应状态码: 

状态码的职责是当客户端向服务器端发送请求时, 返回的请求结果。

借助状态码,用户可以知道服务器端是正常理了请求,还是出现了问题 。

状态码如200 OK,以3位数字和原因组成。

>>状态码的含义,可参考W3C的HTTP1.1标准规范-RFC2616:

https://www.w3.org/Protocols/rfc2616/rfc2616.html

状态码分类汇总

状态码

含义

例子

1XX

通知信息

100=服务器正在处理客户请求

2XX

成功

200=请求成功(ok)

3XX

重定向

301=页面改变了位置

4XX

客户错误

403=静止的页面;404=页面未找到

5XX

服务器错误

500=服务器内部错误;503=以后再试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值