在浏览器中输入网址后,计算机背后都做了些什么事?

本文分享计算机HTTP通信背后的操作。先确定目标地址,若输入域名需经DNS查询IP;接着依次准备HTTP、TCP、网络层、以太网协议通信包,各层数据包有不同结构和设置要求;最后将以太网数据包发送到目标服务器,服务器处理后返回响应,完成一次通信。

首先感谢阮一峰老师的讲解

很长一段时间,都不清楚计算机通信背后所作的事情。经过长时间的经验积累与查询第三方资料,今天我就我所知道计算机通信与大家分享,错误之处还请指正!

1.确定访问的目标地址

浏览器中输入网址后,首先浏览器需要知道访问的目标地址(也就是IP地址),如果,输入的是IP地址(如:172.217.24.14),那就跳过这一步了。

如果是字符串域名,先去DNS域名服务器查询对应域名的IP地址,DNS服务器返回该域名的IP地址,域名服务器的默认访问端口是53。

2.准备HTTP通信包,分为请求头,请求行,请求体,详细的细节这里不在叙述,网上有很多资料。

浏览器(应用层)根据获得的目标IP组装好HTTP请求包。假如是4096个字节,通过建立传输层TCP连接进行通信。

3.准备TCP通信包

首先TCP通信包分为包头(head)和包体(data),上一步中的http通信包放在TCP通信包的包体(data)部分。TCP数据包需要设置端口。

第一步可以拿到接收方的端口,发送方的端口是一个随机端口,范围为0~65535,0~0124端口默认系统占用,一般使用大于1024的端口

TCP数据包包头长度为20字节,加上HTTP协议包4096个字节,总共是 4116字节。

4.准备网络层通信包

IP协议包分为包头和包体,将TCP协议包再嵌入IP协议包的包体(data)部分,IP数据包需要设置访问方和接收方的IP地址,到这一步,IP地址已经是已知的了。

IP协议包的包头为20个字节,加上TCP协议包,总共是4136字节。

5.准备以太网协议通信包

以太网协议包分为包头和包体,将TCP协议包嵌入以太网协议包的包体(data),以太网协议包需要设置双方的MAC地址(物理网卡地址),

发送方为本机的MAC地址,接收方的MAC地址分两种情况:

用双方的IP地址分别与访问方的子网掩码做二进制的与运算,如果结果一致,则双方处于统一子网下,

如果双方处于同一子网下,可以通过ARP协议拿到对方的MAC地址。反之不相等,则不处于同一子网下,比如我的电脑和谷歌的服务器肯定处于不同子网下,

那接收方的MAC地址就是当前子网的网关的MAC地址,以太网协议数据包的数据部分,最大长度为1500字节,所以IP数据包需要拆分成三个包,

每个包都有自己包头,所以三个IP协议包长度为1500,1500,1196

 

 

备注:上图多画了一个数据包,应该是三个不是四个

6.发送数据包

以太网数据包通过网卡发送到多重网关发送到目标服务器,目标服务器根据IP表头的序号,将三个包拼接起来,取出完成的TCP数据包,读出里面的HTTP请求包,

做出响应后,再通过上面的顺便发送响应包到接收方的电脑上,呈现在浏览器中,至此,一次http通信就完成了。

感谢你的反馈!既然你在浏览器中可以正常打开这些图片,说明: - 图片链接是有效的; - 服务器没有对你的 IP 限制; - 站域名 `i1.huishahe.com` 是可以访问的。 那为什么使用 `aiohttp` 异步下载时却出现 `Connection timeout` 或 `403 Forbidden` 呢?这通常是因为服务器了**反爬虫机制**,比如: --- ## ❓常见原因分析: ### ✅ 1. **服务器检查 `User-Agent`** 虽然你设置了 `User-Agent`,但有些站会进一步检查请求头,比如 `Accept`, `Accept-Encoding`, `Referer` 等。 ### ✅ 2. **服务器检查 `Referer`** 有些站会检查请求来源(即 `Referer`),如果为空或不是指定来源,会拒绝请求。 ### ✅ 3. **服务器返回 302 重定向** 有些图片链接会先返回 302 重定向,但 `aiohttp` 默认不会自动跟随,除非你显式设置。 ### ✅ 4. **服务器了 IP 限速或 CDN 限制** 你使用脚本频繁访问,可能被服务器识别为爬虫并限制访问。 --- ## ✅ 解决方案 我们可以尝试以下方式来解决这个问题: --- ### ✅ 方法一:完善请求头(推荐) ```python headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Referer": "https://www.google.com/" # 模拟从谷歌搜索跳转过来 } ``` 在 `session.get(url, headers=headers)` 中使用这个 headers。 --- ### ✅ 方法二:允许自动重定向(`allow_redirects=True`) ```python async with session.get(url, headers=headers, allow_redirects=True) as resp: ``` --- ### ✅ 方法三:禁用 SSL 验证(临时调试) ```python connector = aiohttp.TCPConnector(ssl=False) ``` 完整示例代码如下: --- ## ✅ 优化后的完整代码(带 headers + 重定向 + 忽略 SSL) ```python import aiohttp import asyncio urls = [ "https://i1.huishahe.com/uploads/allimg/202203/9999/a0fa53d1cd.jpg", "https://i1.huishahe.com/uploads/allimg/202206/9999/ef8c2f9839.jpg", "https://i1.huishahe.com/uploads/tu/201911/9999/29fd0b057b.jpg" ] async def aiodownload(url): name = url.split("/")[-1] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Referer": "https://www.google.com/" } connector = aiohttp.TCPConnector(ssl=False) async with aiohttp.ClientSession(connector=connector) as session: try: async with session.get(url, headers=headers, allow_redirects=True) as resp: if resp.status == 200: with open(name, "wb") as f: while True: chunk = await resp.content.read(1024) if not chunk: break f.write(chunk) print(f"{name} 下载完成") else: print(f"{name} 返回状态码: {resp.status}") except Exception as e: print(f"{name} 下载失败: {e}") async def main(): tasks = [asyncio.create_task(aiodownload(url)) for url in urls] await asyncio.gather(*tasks) if __name__ == '__main__': asyncio.run(main()) ``` --- ### ✅ 测试建议: 1. **先测试一个图片链接是否能成功下载**,排除并发影响。 2. **尝试使用代理 IP**(如果你有可用代理)。 3. **更换 User-Agent**,比如使用手机端的 UA。 4. **使用 Selenium 模拟浏览器行为**(更高级的反反爬虫方案)。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值