网络编程
网络编程
1 osi七层,tcp/ip五层
-
cs架构和bs架构
-
互联网
-
osi七层、tcp五层
-
物理层
- 网线,光纤
-
数据链路层
- 网卡
-
网络层
- 路由器
-
传输层(运输层)
- 四层路由器
-
应用层(会话层,表示层,应用层)
- HTTP协议、ftp协议、websocket协议。。。
-
2 每一层功能
- 物理层
- 网线 -》高低电频,传输的是电信号
- 8个比特位是一个字节
- 数据链路层
- 数据帧:一组电信号是一个数据帧,有头和数据部分
- 网卡---》mac地址---》全球唯一,在出厂时就印在了网卡上
- 48位二进制,看到的都是16进制
- 广播:局域网内通信,所有人都会接受到,通过mac地址确定给谁的数据,如果不是自己的就不处理
- 广播风暴
- 网络层
- 跨局域网通信,需要进过网络层
- IP地址:0.0.0.0-255.255.255.255
- 子网掩码:与IP地址进行与运算可以得到网络地址
- ARP协议:IP和mac的对照表
- 传输层
- 端口:0-65535,一个程序可以监听多个端口,但是一个端口只能属于一个应用程序
- TCP协议:可靠传输(三次握手和四次挥手)
- UDP协议:不可靠传输
- 应用层
- HTTP协议,FTP协议,websocket...
3 常用端口号
| 应用程序 | FTP | TFTP | TELNET | SMTP | DNS | HTTP | SSH | MYSQL |
|---|---|---|---|---|---|---|---|---|
| 熟知端口 | 21,20 | 69 | 23 | 25 | 53 | 80 | 22 | 3306 |
| 传输层协议 | TCP | UDP | TCP | TCP | UDP | TCP | TCP | TCP |
DNS:把网络地址转换成ip地址
从浏览器发送出去的数据,都是HTTP协议,默认端口是80
4 TCP三次握手和四次挥手(面试题)
- tcp可靠传输:三次握手,四次挥手保证数据可靠
- 三次握手(建立链接)
- 客户端向服务器端发送链接请求 1
- 服务器端回复可以建立,并且带着跟客户端建立链接的数据报 2
- 客户端收到后。链接建立完成 3
- 这个过程后就可以进行可靠传输数据
- 四次挥手(断开连接)
- 客户端告诉服务端要断开链接 1
- 服务端收到,回复ok 2
- 服务端可能还有数据在传递,暂时还没断开,等待数据传输完毕
- 服务端告诉客户端要断开链接 3
- 客户端收到,回复ok 4
5 Socket层
- socket抽象层,从osi七层中抽象出来的,抽象了网络层和传输层,跟语言无关,任何语言都会有socket的封装
- 专门给开发人员用的

6 基于Tcp的socket套接字(重点)
- 服务端
# 导入socket模块
import socket
import time
# 第一个socket是模块名,第二个socket是类名
#类实例化得到对象,得到一个socket对象
# server=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
#不写默认就是他
server=socket.socket()
# 绑定地址跟端口 ,传一个元组,监听的地址,监听的端口
server.bind(('192.168.11.28',8008))
#监听
# 半连接池是5,可以缓冲5个
server.listen(5)
#等待用户连接(看源码,有两个返回结果)
# sock是连接对象,以后这个服务端和客户端交互,使用这个对象交互
# addr是客户端地址(ip和端口)
sock,addr=server.accept()
# 接收客户端发给我的消息
data=sock.recv(1024)
# 打印
print(data)
#服务端给客户端发送消息(必须是byte格式)
sock.send(b'helloworld')
time.sleep(1)
# 关闭连接对象
sock.close()
#关闭服务
server.close()
- 客户端
import socket
# 创建socket对象
client=socket.socket()
# 连接服务端
client.connect(('127.0.0.1',8008))
#给服务端发了一个sb
client.send(b'sb')
# 收到了服务端给我的
data=client.recv(1024)
print(data)
# 关闭
client.close()
7 加入链接循环的socket套接字TCP
- 服务端
'''
2.1 基于文件类型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
2.2 基于网络类型的套接字家族
套接字家族的名字:AF_INET
(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)
'''
import socket
#实例化得到一个对象
#type=socket.SOCK_STREAM TCP服务端
#type=socket.SOCK_DGRAM UDP服务端
server=socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 绑定地址和端口
server.bind(('127.0.0.1',80))
# listen:监听
server.listen(1)
# 等待用户连接
print('开始等待客户端连接了')
while True:
sock,addr=server.accept()
print(sock)
print('客户端的地址是:',addr)
data=sock.recv(1024)
print(data)
# 这不是字符串的upper
sock.send(data.upper())
sock.close()
server.close()
- 客户端
import socket
client=socket.socket()
client.connect(('127.0.0.1',80))
client.send('sb'.encode('utf-8'))
data=client.recv(1024)
print(data)
client.close()
8 加入通信循环的socket套接字TCP
- 服务端
import socket
server=socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
server.bind(('127.0.0.1',81))
server.listen(1)
print('开始等待客户端连接了')
while True:
sock,addr=server.accept()
print(sock)
print('客户端的地址是:',addr)
# 等待客户端发送过来的数据,如果客户端没有发送数据,会一直等着
while True:
try:
data=sock.recv(1024)
if len(data)==0: # 这个表示客户端正常断开了,结束通信循环
break
print(data.decode('utf-8'))
sock.send(data.upper())
except Exception as e:
print(e) #客户端非正常断开,需要异常捕获
break
sock.close()
server.close()
- 客户端
import socket
client=socket.socket()
client.connect(('127.0.0.1',81))
while True:
input_data=input('请输入发送给客户端的内容(输入q退出):')
if input_data=='q':
break
client.send(input_data.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8'))
client.close()
9 基于UDP的socket套接字
- 服务端
import socket
# udp的服务端
server = socket.socket(type=socket.SOCK_DGRAM)
# 监听地址和端口
server.bind(('127.0.0.1', 82))
# 不需要listen,直接建立链接
print('等待客户端发送数据:')
while True:
#recvfrom回返回数据和客户端的地址
data,addr = server.recvfrom(1024)
print(data)
print(addr)
server.sendto(data.upper(), addr)
server.close()
- 客户端
import socket
client=socket.socket(type=socket.SOCK_DGRAM)
client.sendto(b'sb',('127.0.0.1',82))
# data,addr=client.recvfrom(1024)
# data,_=client.recvfrom(1024)
data=client.recv(1024)
print(data)
# print(addr)
client.close()

浙公网安备 33010602011771号