1. 套接字通信循环
# **********server.py*********
import socket
# 生成一个socket对象
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定地址跟端口号
soc.bind(('127.0.0.1',8000))
# 监听(半连接池的大小)
soc.listen(5)
# 等着客户端来连接,conn相当于连接通道,addr是客户端的地址
conn,addr = soc.accept() # 卡住,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
print(addr)
while True:
try:
# 等待接收,最大收取1024个字节
data = conn.recv(1024) # 会卡住,当客户端有数据传过来,才会执行
print(data)
except Exception:
# 关闭通道
conn.close()
break
# 关闭套接字
soc.close()
# *********client.py********
import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8000))
while True:
inp_s = input('请输入要发送的数据:')
# 发送的数据必须是b格式,inp_s.encode('utf-8') 把字符串编码成b格式
# # 把b格式转成字符串
# ss = str(b'hello',encoding='utf-8')
# ss = b'hello'.decode('utf-8')
# # 把字符串转成b格式
# by = bytes('hello',encoding='utf-8')
# by = 'hello'.encode('utf-8')
soc.send(inp_s.encode('utf-8'))
2. 套接字连接循环
# **********server.py*********
import socket
# 生成一个socket对象
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定地址跟端口号
soc.bind(('127.0.0.1',8000))
# 监听(半连接池的大小),不是连接数
soc.listen(5)
while True:
# 等着客户端来连接,conn相当于连接通道,addr是客户端的地址
print('等待客户端连接')
conn,addr = soc.accept() # 卡住,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
print('已有客户连接:',addr)
while True:
try:
# windows如果客户端断开,会报错,加了try
# linux如果客户端,断开,不会报错,会收到空,所有当data为空时,也break
# 等待接收,最大收取1024个字节
data = conn.recv(1024) # 会卡住,当客户端有数据传过来,才会执行
if len(data) == 0: #处理linux客户端断开,如果在window下这段代码根本不会执行(即便是客服端发了空,这个地方也不会走到)
break
print(data)
except Exception:
break
# 关闭通道
conn.close()
# 关闭套接字
soc.close()
# *********client.py*********
import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8000))
while True:
inp_s = input('请输入要发送的数据:')
# 发送的数据必须是b格式,inp_s.encode('utf-8') 把字符串编码成b格式
# # 把b格式转成字符串
# ss = str(b'hello',encoding='utf-8')
# ss = b'hello'.decode('utf-8')
# # 把字符串转成b格式
# by = bytes('hello',encoding='utf-8')
# by = 'hello'.encode('utf-8')
soc.send(inp_s.encode('utf-8'))
3. 模拟ssh功能
# ******subprocess.py*******
#ssh 是远程执行命令
#subprocess 执行系统命令的模块
import subprocess
#执行系统dir命令,把执行的正确结果放到管道中
# obj=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
obj=subprocess.Popen('tasklistdd',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#拿到正确结果的管道,读出里面的内容
ss=obj.stdout.read()
err=obj.stderr.read()
print('错误信息',str(err,encoding='gbk'))
#因为windows用的gbk编码,用gbk解码
# print(str(ss,encoding='utf-8'))
print(str(ss,encoding='gbk'))
# ********server.py********
import socket
import subprocess
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8001))
soc.listen(3)
while True:
print('等待客户端连接')
conn,addr=soc.accept()
print('有个客户端连接上了',addr)
while True:
try:
data=conn.recv(1024)
if len(data)==0:
break
print(data)
obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#执行正确的结果 b 格式,gbk编码(windows平台)
msg=obj.stdout.read()
#把执行的结果通过网络传给c端
conn.send(msg)
except Exception:
break
# 关闭通道
conn.close()
# 关闭套接字
soc.close()
# *******client.py*********
import socket
soc=socket.socket()
soc.connect(('127.0.0.1',8001))
while True:
in_s=input('请输入要执行的命令:')
soc.send(in_s.encode('utf-8'))
data=soc.recv(1024)
print(str(data,encoding='gbk'))
#粘包:tcp会把数据量较小,时间间隔较短的数据,当做同一个包发送
4. 粘包问题
# *******server.py*********
import socket
#生成一个socket对象
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定地址跟端口号
soc.bind(('127.0.0.1',8001))
#监听(半连接池的大小),不是连接数
soc.listen(3)
#等着客户端来连接,conn相当于连接通道,addr是客户端的地址
while True:
print('等待客户端连接')
conn,addr=soc.accept() #卡主,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
print('有个客户端连接上了',addr)
while True:
try:
data=conn.recv(1024)
print(data)
data2=conn.recv(1024)
print(data2)
data3=conn.recv(1024)
print(data3)
except Exception:
break
# 关闭通道
conn.close()
# 关闭套接字
soc.close()
# ********client.py********
import socket
soc=socket.socket()
soc.connect(('127.0.0.1',8001))
while True:
in_s=input('请输入要发送的数据:')
soc.send(b'a')
soc.send(b'b')
soc.send(b'c')
5. 解决粘包问题
# ********struct模块********
import struct
#把一个数字打包成固定长度的4字节
obj=struct.pack('i',1098)
print(obj)
print(len(obj))
l=struct.unpack('i',obj)[0]
print(l)
# ********server.py*********
import socket
import subprocess
import struct
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8001))
soc.listen(3)
while True:
print('等待客户端连接')
conn,addr=soc.accept()
print('有个客户端连接上了',addr)
while True:
try:
data=conn.recv(1024)
if len(data)==0:
break
print(data)
obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#执行正确的结果 b 格式,gbk编码(windows平台)
msg=obj.stdout.read()
#发送的时候需要先把长度计算出来
#头必须是固定长度
#10
#100
#先取出要发送数据长度l
l=len(msg)
#head 是固定四个字节
head=struct.pack('i',l)
#发了头
conn.send(head)
#发了内容
conn.send(msg)
except Exception:
break
# 关闭通道
conn.close()
# 关闭套接字
soc.close()
# ********client.py********
import socket
import struct
soc=socket.socket()
soc.connect(('127.0.0.1',8001))
while True:
in_s=input('请输入要执行的命令:')
soc.send(in_s.encode('utf-8'))
head=soc.recv(4)
l=struct.unpack('i',head)[0]
# data=soc.recv(l)
count=0
data_total=b''
while count<l:
if l<1024: #如果接受的数据小于1024 ,直接接受数据大小
data=soc.recv(l)
else:#如果接受的数据大于1024
if l-count>=1024: #总数据长度-count(目前收到多少,count就是多少) 如果还大于1024 ,在收1024
data=soc.recv(1024)
else: #总数据长度-count(目前收到多少,count就是多少) 如果小于1024,只收剩下的部分就可
data=soc.recv(l-count)
data_total+=data
count+=len(data)
print(str(data_total,encoding='gbk'))
6. 解决粘包问题终极版
# ********struct模块*********
import struct
import json
import struct
head={'size':100999999999999999999999990000000000000000000000000000000000000000,'md5':'sdfsdfasdf','filename':'a.txt'}
head_str=json.dumps(head)
head_bytes=head_str.encode('utf-8')
print(len(head_bytes))
obj=struct.pack('i',len(head_bytes))
print(obj)
print(len(obj))
#发
send(obj)
send(head_bytes)
send(b'ddddddddddddddddddd')
#收
obj=recv(4)
head_len=struct.unpack('i',obj)[0]
head_bytes=recv(head_len)
head_dic=json.loads(head_bytes)
l=head_dic['size']
# *******server.py**********
import socket
import subprocess
import struct
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8001))
soc.listen(3)
while True:
print('等待客户端连接')
conn,addr=soc.accept()
print('有个客户端连接上了',addr)
while True:
try:
data=conn.recv(1024)
if len(data)==0:
break
print(data)
obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#执行正确的结果 b 格式,gbk编码(windows平台)
msg=obj.stdout.read()
#发送的时候需要先把长度计算出来
#头必须是固定长度
#先发4位,头的长度
import json
dic={'size':len(msg)}
dic_bytes=(json.dumps(dic)).encode('utf-8')
#head_count是4个字节的长度
head_count=struct.pack('i',len(dic_bytes))
print(dic)
conn.send(head_count)
#发送头部内容
conn.send(dic_bytes)
#发了内容
conn.send(msg)
except Exception:
break
# 关闭通道
conn.close()
# 关闭套接字
soc.close()
# ********client.py*********
import socket
import struct
import json
soc=socket.socket()
soc.connect(('127.0.0.1',8001))
while True:
in_s=input('请输入要执行的命令:')
soc.send(in_s.encode('utf-8'))
#头部字典的长度
head_dic_len=soc.recv(4)
#解出真正的长度
head_l=struct.unpack('i',head_dic_len)[0]
#byte 字典的长度
#收真正的头部字典
dic_byte=soc.recv(head_l)
head=json.loads(dic_byte)
print(head)
l=head['size']
count=0
data_total=b''
print(l)
while count<l:
if l<1024: #如果接受的数据小于1024 ,直接接受数据大小
data=soc.recv(l)
else:#如果接受的数据大于1024
if l-count>=1024: #总数据长度-count(目前收到多少,count就是多少) 如果还大于1024 ,在收1024
data=soc.recv(1024)
else: #总数据长度-count(目前收到多少,count就是多少) 如果小于1024,只收剩下的部分就可
data=soc.recv(l-count)
data_total+=data
count+=len(data)
print(str(data_total,encoding='gbk'))