python 18 网络编程
网络编程
1.osi七层、tcp/ip五层协议
1.cs架构和bs架构
2.互联网
3.osi七层、五层协议
-物理层
-网线、光纤
-数据链路层
-网卡
-网络层
-路由器
-传输层(运输层)
-四层路由器
-应用层(会话层、表示层、应用层)
-http协议,tfp协议,websocket协议
2.每一层功能
1.物理层
-网线——> 101010101电信号——>从网线中传输电信号
-8个bit位是一个字节
2.数据链路层
-数据帧:一组电信号是一个数据帧,有头和数据部分
-网卡——>mac地址——>全球唯一——>网卡出厂——>烧在了网卡上
-48位二进制——>看到的是12位16进制表示
-广播
-局域网内通信,通过mac确定给谁的数据报,所有人都会接收到,如果不是自己的就不处理
-广播风暴
3.网络层
-跨局域网通信,需要经过网络层
-ip地址
-子网掩码
-192.168.1.1 255.255.255.0
-192.168.2.1 255.255.255.0
-arp协议:ip和mac的对照表
4.传输层
-端口:0-65535,一个应用程序可以监听多个端口,但是一个端口只能属于一个应用程序
-tcp协议:可靠传输(可靠传输如何保证?三次握手,四次挥手)
-udp协议:不可靠传输
5.应用层
-http,ftp,websocket....
2.1常用端口号
应用程序 | FTP | TFTP | TELNET | SMTP | DNS | HTTP | SSH | MYSQL |
---|---|---|---|---|---|---|---|---|
熟知端口 | 21,22 | 69 | 23 | 25 | 53 | 80 | 22 | 3306 |
传输层协议 | TCP | UDP | TCP | TCP | UDP | TCP | TCP | TCP |
3.tcp三次握手和四次挥手(面试题)
1.tcp可靠传输,三次握手、四次挥手保证数据可靠
2.三次握手
-客户端向服务端发送链接请求
-服务端回复可以建立,并且带着跟客户端建立链接的数据报
-客户端收到后回复可以建立
3.断开链接、四次挥手
-客户端告诉服务端,要断开 1
-服务端收到,并回复 2
-服务端可能还在传输数据,等数据传完
-服务端告诉客户端,要断开链接 3
-客户端收到回复 4
4.Socket层
1. Socket抽象层,从osi七层抽象出来的,抽象了网络层和传输层,跟语言无关,任何语言都会有socket的封装
2.专门给开发人员用的
5.基于tcp的socket的套接字(重点)
服务端
import socket
# sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk = socket.socket() # 不写默认也是上面的参数
# 绑定地址和端口以一个元组的形式
sk.bind(('192.168.137.1', 9000))
# 半连接池是2
sk.listen(2)
# conn是连接对象,以后这个客户端和服务端交互就用这个对象
# addr是客户端地址(ip和端口)
conn, addr = sk.accept()
# 接收客户端发送的消息
data = conn.recv(1024)
# 打印
print(data.decode())
# 服务端给客户端发送消息(必须是byte格式)
conn.send('sb'.encode())
# 关闭连接对象
conn.close()
# 关闭服务
sk.close()
客户端
import socket
client = socket.socket()
client.connect(('192.168.137.1', 9000))
client.send('sb'.encode())
data = client.recv(1024)
print(data.decode())
作业
2 写一个tcp套接字服务端,和客户端
3.写套接字服务端和客户端传文件
from math import ceil
import socket
# sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk = socket.socket() # 不写默认也是上面的参数
# 绑定地址和端口以一个元组的形式
sk.bind(('192.168.11.213', 9000))
# 半连接池是2
sk.listen(2)
while True:
# conn是连接对象,以后这个客户端和服务端交互就用这个对象
# addr是客户端地址(ip和端口)
conn, addr = sk.accept()
# while True:
# # 接收客户端发送的消息
# data = conn.recv(1024)
#
# # 打印
# print(data.decode())
#
# if not data:
# break
with open('../../18.png', 'rb') as f:
for res in f:
# for i in range(ceil(len(response) // 1024)):
# # print(i)
# res = response[i * 1024:(i + 1) * 1024]
# response = input(">>>>").strip().encode()
# 服务端给客户端发送消息(必须是byte格式)
conn.send(res)
print('has sent')
# 关闭连接对象
conn.close()
# 关闭服务
sk.close()
# 客户端
import socket
client = socket.socket()
client.connect(('192.168.11.213', 9000))
# client.send('dsb'.encode())
#
# data = client.recv(1024)
#
# print(data.decode())
while True:
with open('xx.png', 'wb') as f:
while True:
d = client.recv(1024)
print(d)
f.write(d)