recv()特征
1.如果连接端断开,recv会立即结束阻塞返回空字符串
2.当接收缓冲区为空时会阻塞
3.如果recv一次接收不完缓冲区内容,下次会继续接收,确保数据不丢失
send()特征
1.如果另一端不存在还试图使用send进行发送,则会产生BrokenPeError异常
2.当发送缓冲区满时会阻塞
网络收发缓冲区
*缓冲区的功能 :协调读写速度,减少和磁盘交互
recv 和 send 实际上是从缓冲区获取内容,和向缓冲区发送内容
tcp粘包
产生原因: tcp传输采用字节流的方式,消息之间没有边界,如果发送和接受速度不匹配,
会造成多次发送的内容被一次接受,形成意义上的误解即粘包
产生条件:当使用send快速的连续发送极有可能产生粘包
影响:如果每次发送的内容代表一个独立的意思,此时产生粘包需要处理,
但是如果多次发送的内容本身就是一个连续的整体,此时就不需要处理。
如何处理:
1.每次发送后加一个结尾标志,接收端通过标志进行判断
2.发送一个数据结构
3.每次发送中间有一个短暂的延迟
基于udp的通信
服务端
1.创建套接字 --->> 数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
2.绑定服务端地址
sockfd.bind()
3.消息的收发
data,addr = recvfrom(buffersize)
功能:接受udp
消息参数:每次最多接收消息的大小
返回值:data 接收到的消息
addr 消息发送者的地址
sendto(data,addr)
功能:udp发送消息
参数:data要发送的消息 bytes
addr 目标地址
返回值:发送的字节
4.关闭套接字
sockfd.close()
cookie
sys.argv
功能:获取来自命令行的参数,形成一个列表
* 以空格作为每一项分隔,如果一项中有空格则用引号表示一个整体
* 命令行内容均作为字符串传入
from socket import *
import sys
#从命令行传入ip和端口
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
sockfd = socket(AF_INET,SOCK_DGRAM)#创建数据报套接字
sockfd.bind(ADDR)#绑定地址
while True:
data,addr = sockfd.recvfrom(5) #接受消息
print("Receive from %s:%s"%(addr,data.decode()))
sockfd.sendto("收到你的消息".encode(),addr) #发送消息
sockfd.close()#关闭套接字
from socket import *
import sys
if len(sys.argv) < 3:
print('''
argv is error !!
run as
python3 udp_client.py 127.0.0.1 8888
''')
raise
HOST = sys.argv [1]
PORT = int(sys.argv[2])
SERVER_ADDR = (HOST,PORT)
sockfd = socket(AF_INET,SOCK_DGRAM)#创建套接字
while True:
data = input("消息:")
if not data:
break
sockfd.sendto(data.encode(),SERVER_ADDR) #给服务器发送
data,addr = sockfd.recvfrom(1024)#收到服务器回复
print("从服务器收到:",data.decode())
sockfd.close()
udp客户端
1.创建套接字
2.消息收发
3.关闭套接字
from socket import *
sockfd = socket(AF_INET,SOCK_STREAM)#创建tcp套接字
sockfd.bind(("127.0.0.1",8888))#绑定IP和端口
sockfd.listen(5)#设置监听
while True:
print("Waiting for connect....")
connfd,addr = sockfd.accept() #等待客户端链接
print("Connect from",addr)
while True:
data = connfd.recv(1024) #接收
if not data:
break
print("Receive message >>",data.decode())
n = connfd.send(b"Receive your message\n") #发送
print("Send %d bytes data"%n)
connfd.close() #关闭套接字
sockfd.close()
from socket import *
sockfd = socket()#创建套接字 tcp 默认参数即可
sockfd.connect(('127.0.0.1',8888))#发起链接请求
while True:
data = input("发送>>")
if not data:
break
sockfd.send(data.encode()) #发送消息 bytes格式
data = sockfd.recv(1024).decode()
print(data)
sockfd.close()#关闭套接字
tcp流式套接字 和 udp数据报套接字 区别
1.流式套接字采用字节流的方式传输数据,而数据报套接字以数据报形式传输
2.tcp会产生粘包现象,udp消息是有边界的不会粘包
3.tcp传输是建立在连接的基础上,保证传输的可靠性,而udp一次接受一个数据报,不保证完整性
4.tcp需要依赖listen accept建立连接,udp不用
5.tcp收发消息使用recv send udp用recvfrom sendto
补充
sendall()
功能:同send() 作为tcp消息发送
参数:同send()
返回值:发送成功返回None,发送失败返回异常
socket模块和套接字属性
(s表示一个套接字对象)
s.type : 获取套接字类型
s.family:获取地址族类型
s.fileno()
功能:获取套接字的文件描述符
文件描述符:每一个IO操作系统都会为其分配一个不同的正整数,该正整数即为此IO操作的文件描述符
s.getsockname()
功能:获取套接字绑定地址
s.getpeername()
功能:获取连接套接字另一端的地址
s.setsockopt(level,optname,value)
功能:设置套接字选项 丰富修改原有套接字功能
参数:lever : 获取选项的类型
optname:每个选项类型中的子选项
value:为选项设置值
from socket import *
s = socket()
print(s.type) #获取套接字类型
print(s.family) #获取地址族类型
print(s.fileno()) #获取文件描述符
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#设置端口可重用
print(s.getsockopt(SOL_SOCKET,SO_REUSEADDR)) #获取选项值
s.bind(('172.60.50.93',8888))
print(s.getsockname()) #获取绑定地址
s.listen(5)
c,addr = s.accept()
print(c.getpeername())#获取链接端地址
data = c.recv(1024)
print(data)
c.close()
s.close()
udp套接字应用之广播
一点发送多点接收
目标地址: 广播地址,每个网段内最大的地址
172.60.50.255 --->> <broadcast>
cookie
format()
功能:合成字符串
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:
print("接收消息结束")
break
except Exception as e:
print(e)
s.close()
from socket import *
from time import sleep
dest = ('172.60.50.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()
tcp应用之HTTP传输
http协议 --->> 超文本传输协议 应用层协议
用途:网页的获取,基于网站的数据传输
基于http协议的数据传输
特点:
1.应用层协议,传输层使用tcp传输
2.简单灵活,和多种语言对接方便
3.无状态协议,不记录用户的通信内容
4.成熟稳定 http1.1
工作模式:
* 使用http双方均遵循http协议规定发送接收消息体
* 请求方,根据协议组织请求内容发送给对方
* 服务方,收到内容按照协议解析
* 服务方,将回复内容按照协议组织发送给请求方
* 请求方,收到回复根据协议解析
http请求
http响应
作业:写一个tcp服务端和客户端,完成一个文件的传输过程
了解http协议更多能容
read --> send
recv --> write