连接循环/通信循环
话不多说,直接上代码
# 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: #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',8001)) while True: in_s=input('请输入要发送的数据:') #发送的数据必须是b格式,in_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(in_s.encode('utf-8'))
粘包问题
粘包:tcp会把数据量较小,时间间隔较短的数据,当做同一个包发送
# 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')
模拟ssh功能
# 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()
# clinet.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会把数据量较小,时间间隔较短的数据,当做同一个包发送
解决粘包终极版
# 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'))
精彩评论