【sockets套接字编程】
1.目的:
通过编程语言提供的函数接口进行组合,更简单的完成基于tcp或者udp通信的网络编程
2.套接字:
完成上述目标的一种编程方法
3.套接字分类:
流式套接字(SOCK_STREAM): 传输层基于tcp的协议进行通信
数据报套接字(SOCK_DGRAM): 传输层基于udp协议进行通信
底层套接字(SOCK_RAM): 访问底层协议的套接字
【tcp流式套接字和udp数据报套接字使用区别】
-
流式套接字采用字节流的方式传输,而数据报套接字以数据包形式传输
-
tcp会产生粘包现象,udp不会
-
tcp编程保证数据传输的可靠性,udp则不保证
-
tcp需要listen accecp,udp不需要
-
tcp使用recv send进行消息收发,udp使用recvfrom和sendto
【补充】
sendall()
功能:同send
参数:同send
返回值:发送成功返回None,发送失败返回异常
【套接字对象】
(s表示一个套接字对象)
s.fileno()
功能:
获取套接字的文件描述符
文件描述符:
每一个IO事件操作系统都会分配一个不同的正数与之匹配,该正数即为此IO操作的文件描述符
sys.stdin 0
sys.stdout 1
sys.stderr 2
In [1]: import sys
In [2]: sys.stdin.fileno()
Out[2]: 0
In [3]: sys.stdout.fileno()
Out[3]: 1
In [4]: sys.stderr.fileno()
Out[4]: 2
s.type:获取套接字的类型
s.family: 地址类型
s.getsockname()
功能:获取套接字绑定的地址
s.getpeername()
功能:用户连接套接字,获取连接端的地址
s.setsockopt(level,optname,value)
功能:
设置套接字选项
参数:
leval:设置选项的类型
IPPROTP_TCP IPPROTO_IP
SOL_SOCKET
optname:选项类型中的子选项
value:为选定的选项设置值
s.getsockopt(level,optname)
功能:获取套接字选项值
参数:
leval:获取选项的类型
IPPROTP_TCP IPPROTO_IP
SOL_SOCKET
optname:选项类型中的子选项
返回值:
获取到的值
【udp套接字应用之广播】
一点发送多点接收
目标地址:广播地址 一个网段内最大的地址
广播:176.130.5.255
广播风暴:
占用大量的带宽造成网络拥塞
示例:
broadcast_send.py
from socket import *
from time import sleep
# 广播地址
dest = ('176.130.5.255',9999)
# 创建数据报套接字
s = socket(AF_INET,SOCK_DGRAM)
# 设置套接字可以发送接收广播
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
while True:
sleep(2)
s.sendto('恬恬^_^'.encode(),dest)
s.close()
broadcast_recv.py
from socket import *
# 创建数据报套接字
s = socket(AF_INET,SOCK_DGRAM)
# 设置可以接收广播
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
# 固定端口号
s.bind(('',9999))
while True:
try:
msg,addr = s.recvfrom(1024)
print('从{}获取信息:{}'.\
format(addr,msg.decode()))
except (KeyboardInterrupt,SyntaxError):
raise
except Exception as e:
print(e)
s.close()
【tcp应用之http传输】
-
HTTP协议—>超文本传输协议
-
用途:
编写基于http协议的数据传输程序
网站中浏览器端获取网页的过程 -
作用:
将想要获取的内容以http协议的格式发送给服务端,
服务端根据格式进行解析获取到真实需求,
将结果以http协议的格式回复给客户端 -
特点:
- 应用层协议,传输层使用tcp服务
- 简单、灵活、和多种语言对接方便
- 无状态的协议,即不记录用户使用过程中传递的内容
- http1.1版本 支持持久连接
-
请求与响应:
http请求(Request)
请求格式:
请求行:具体的请求类别
GET / HTTP/1.1
请求种类 请求内容 协议版本
请求头:对请求信息的具体描述
Accept:text/html
以键值对的格式对信息进行具体描述空行
请求体:具体的请求参数或者提交内容
请求类型:
GET:获取网络资源
POST:提交一定的附加数据,得到返回结果
HEAD:获取响应头
PUT:更新服务器资源
DELETE:删除服务器资源
CONNECT:#保留,暂无作用
TRACE:用于测试
OPTIONS:获取服务端性能
HTTP响应(Response)
是服务器给客户端发
响应格式:
响应行:反馈具体的响应情况
HTTP/1.1 200 OK
版本 响应码 附加信息
响应码:
1xx 提示信息,表示请求已被接受
2xx 响应成功
3xx 响应需要重定向
4xx 客户端错误
5xx 服务端错误
如:200 响应成功
404 请求内容不存在
401 没有访问权限
500 服务器发生未知错误(bug)
503 服务器暂时不能执行响应头:对响应的具体描述
Accept-Ranges:bytes
以键值对方式给出响应信息的具体描述
空行
响应体:将客户想要的内容进行返回
要求: 什么是http协议
请求格式和每部分的功能
响应格式和每部分功能
http请求和响应的流程
httpserver (HTTP协议):
1. 接收浏览器的连接
2. 将接收内容解析
3. 组织响应内容
4. 将响应内容回发给浏览器
【本地套接字】
-
Linux下文件类型:
b(快设备文件)
c(字符设备文件 显示器、键盘等)
d(目录/文件夹)
-(普通文件 压缩包、音视频、文本)
l(链接文件)
s(套接字文件)
p(管道文件)
(套接字文件不占磁盘空间的,始终在内存中运行)
srwxrwxr-x 1 tarena tarena 0 6月 8 11:07 sock_file
(所以大小为0) -
作用:
用于本地不同的程序间进行通信
(在Linux和Unix操作系统下,提供本地进程间通信的一种方式) -
本地套接字创建流程:
- 创建套接字对象(文件)
sockfd = socket(AF_UNIX,SOCK_STREAM) - 建立套接字文件
sockfd.bind(path)绑定一个文件
path是一个文件的路径字符串 - 监听
- 接收发送消息
- 创建套接字对象(文件)
-
补充:
os.path.exists(path)
功能:判断一个文件是否存在
参数:文件位置
返回值:存在返回True,否则返回False
os.unlink() os.remove
功能:删除一个文件
参数:要删除的文件路径
unix_recv.py
from socket import *
import os
# 确定使用哪个套接字文件
sock_file = './sock_file'
# 如果已经存在同名的文件则删除
if os.path.exists(sock_file):
os.unlink(sock_file)
# 创建本地套接字
sockfd = socket(AF_UNIX,SOCK_STREAM)
# 绑定套接字文件
sockfd.bind(sock_file)
# 监听
sockfd.listen(5)
# 消息收发
while 1:
connfd,addr = sockfd.accept()
while 1:
data = connfd.recv(1024)
if data:
print(data.decode())
connfd.send(b'Receive your message')
else:
break
unix_send.py
# 本地套接字发送端
from socket import *
# 确保和另一端使用相同的套接字文件
sock_file = './sock_file'
# 创建本地套接字
sockfd = socket(AF_UNIX,SOCK_STREAM)
# 连接另一端
sockfd.connect(sock_file)
# 收发消息
while 1:
msg = input('>>>')
if msg:
sockfd.send(msg.encode())
data = sockfd.recv(1024).decode()
print('收到消息:',data)
else:
break
sockfd.close()