send与recv 的基础概念、两者之间的工作原理、粘包产生原理
不管是recv 还是 send 不是直接接收对方数据,都是对自己的操作系统内存操作, 不是一个send对应一个recv
recv:
wait data 耗时非常长,需要等待
copy data
send:
copy data
- send过程中:TCP协议优化如果两次向内存send时间非常相近则会将两个包 粘在一起发送
- recv过程中:如果接收字节大于1024 则会将剩余的字节存在内存中,下次recv的时候优先取出上次未取出的数据
UDP 与 TCP 区别
- 通常 查询功能,效率高 (查询百度时间等等) DNS服务等
- UDP协议即便发送 ’‘ 空 ,也会相互发送交互, 因为会发送 端口ip信息
- UDP不会粘包,
recvfrom()
和sendto()
必须1对1
服务器端
from gevent import monkey, spawn; monkey.patch_all() # 使用gevent必须 调用
import socket
def communicate(conn):
while True:
try:
data = conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
def server(ip, port):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.bind((ip,port))
soc.listen(5)
while True:
conn, der = soc.accept()
spawn(communicate, conn) # 协程开启处理IO问题
soc.close()
if __name__ == '__main__':
g = spawn(server, '127.0.0.1', 8080) # 开启协程, 异步提交
g.join()
客户端
import socket
from threading import Thread,currentThread
def client():
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect(('127.0.0.1', 8080))
while True:
soc.send(('%s hello' % currentThread().getName()).encode('utf-8'))
data = soc.recv(1024)
print(data.decode('utf-8'))
soc.close()
if __name__ == '__main__':
for i in range(500): # 模拟500个 用户交互
t = Thread(target=client) # 线程开启
t.start()