一.tcp : 属于长连接 与客户端连接了之后 其他客户端需要等待 要连接另外一个 必须优雅的断开前面这个客户的连接.
二.缓冲区 :为了避免网络传输信号不通畅而是程序一直停留在消息发送状态而不向下进行.
每个socket被创建后 都会分配两个缓冲区 ,输入缓冲区和输出缓冲区
write()/send()并不立即向网络中传输数据 而是先写入缓冲区 再由tcp协议将数据从缓冲区发送到目标机器 一旦写入到缓冲区 函数就可以成功返回 继续进行接下来的操作 不管数据有没有到达目的机器 也不管何时被发送到网络.接收也一样.
缓冲区特性:
1.I/O缓冲区在每个TCP套接字中单独存在
2.I/O缓冲区在创建套接字时自动生成
3.即使关闭套接字也会继续传输缓冲区遗留的数据:
4.关闭套接字将丢失缓冲区域的数据
三.粘包(tcp) :
(1) 发两条信息 但是在客服端一下拼接起来给显示出来 比如 先发送一个 12再发送一个 3 要求计算12/3 但是过去显示为 123 此现象即为粘包现象
粘包需要先引入一个模块 subprocess
import subprocess cmd = input('请输入指令>>>') res = subprocess.Popen( cmd,# 字符串指令 : 'dir','ipconfig'等等 shell=True,# 使用shell 就相当于使用cmd窗口 stderr=subprocess.PIPE,#标准错误输出,凡是指令输出的错误信息就会被他拿到 stdout=subprocess.PIPE#标准输出,正确指令的输出结果被它拿到 ) print(res.stdout.read().decode('gbk')) print(res.stderr.read().decode('gbk'))
客户端:
import socket client = socket.socket() server_ip_port = ('192.168.155.1',8006) client.connect(server_ip_port) client.send('hello'.encode('utf-8')) client.send('sigui'.encode('utf-8')) client.close()
服务端:
server.bind(ip_port) server.listen() conn,addr = server.accept() from_client_msg1 = conn.recv(1024).decode('utf-8') from_client_mag2 = conn.recv(1024).decode('utf-8') print('msg1',from_client_msg1) print('mag2',from_client_mag2) conn.close() server.close()
结果为 :
msg1 hellosigui
mag2
两次连接到一起传给服务端
(2) 客户第一次发送了一条2000B的数据 第二次发送1000B的数据 服务端每次接收1024B结果就是 第一次接收1024 B 第二次接收客户端第一次信息的976 + 第二次24 就比较乱了
根本原因 : 服务端不知道客户端发送的数据大小是多少.
send 和 send all 的区别:
使用send发送的时候 Python将内容传递给系统底层的send接口,也就是说,Python并不知道这次调用是否会全部发送完成 ,比如MTU(Maximum Transmission Unit 最大传输单元 指的是能传输的最大数据包大小(以字节为单位)) 是1500 但是此次发送的内容是2000 , 那么除了包头等其他信息占用 发送量可能在1000左右 , 还有1000未发送完毕 而此时的send不会再进行第二次发送 因为他只发送一次 如果想将剩下的1000发送完毕 需要自行获取返回结果 然后将剩下的内容继续调用fsend发送
sendall()是对 send的包装 完成了用户需要手动完成的部分 会自动判断每次发送的内容量 将剩下的继续传递给send()进行发送:
一般情况下我们都应该使用sendall()
find 和 findall 的区别:
find()用法 : find(name , attrs , recursive , text , **wargs)
查找标签 , 基于name参数
查找文本 , 基于text参数
基于正则表达式的查找
查找标签的属性 , 以及基于attrs参数
基于函数的查找
find_all()用法 相比find() find_all() 有一个额外的参数limit 如 p = soup.find_all(text = 'algae',limit=2) 其实 find()就是当limit=1时的find_all()
find_all() 方法没有找到目标时返回的是空列表 find()方法找不到目标时返回的是None.