标签:
网络编程基础(一)
#coding=gbk import socket HOST = ‘‘ PORT = 321 s=socket.socket() s.bind((HOST,PORT)) s.listen(5) client,addr=s.accept()#接收客户端的连接,返回一个客户端, print(‘client address:‘,addr) while True: data = client.recv(1024)#接收数据 if not data:#为空,断开连接 break else: print(‘receive data :‘,data.decode(‘utf-8‘))#数据不为空,输出 client.send(data)#将数据发挥客户端 client.close() s.close()
#coding=gbk import socket HOST = ‘‘ PORT = 3214 #socket.socket(family,type) family表示套接字使用什么版本协议 Type=SOCK_STREAM(使用TCP) type=sock_DGRAM(UDP协议) s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#使用iPv4协议 s.bind((HOST,PORT)) data = True while data: data,addr = s.recvfrom(1024) if data==b‘bye‘:#为空,断开连接 break else: print(‘receive data :‘,data.decode(‘utf-8‘))#数据不为空,输出 s.send(data,addr)#将数据发挥客户端 s.close()
#coding=gbk import socket HOST = ‘127.0.0.1‘ PORT = 3215 s=socket.socket() try: s.connect((HOST,PORT)) data="nihao!" while data: s.sendall(data.encode(‘utf-8‘))#编码发送出去的信息 data=s.recv(1024)#接收数据 print(‘reveive is :\n‘,data.decode(‘utf-8‘))#解码打印收到的数据 data=input(‘please input string:\n‘) except socket.errno as err: print(err) finally: s.close()
#coding=gbk import socket HOST = ‘127.0.0.1‘ PORT = 3215 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#使用iPv4协议) data=‘nihao‘ while data: s.sendto(data.encode(‘utf-8‘),(HOST,PORT))#编码发送出去的信息 if data==‘bye‘: break data,addr=s.recvfrom(1024) print(‘receive is :\n‘,data.decode(‘utf-8‘)) data=input(‘please input string:\n‘) s.close()
#coding=gbk from tkinter import * from tkinter.ttk import * import socket import struct def start(host,port): pass def MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.local_ip=‘127.0.0.1‘#服务器端默认的IP地址 self.serv_ports=[10888,20888,30888]#三个服务器的端口 self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份服务器‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Combobox(self,values=self.get_ipaddr()) #设置默认的服务器的ip地址 self.serv_ip.set(self.local_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Combobox(self,values=self.serv_ports) #设置默认的服务端口 self.serv_port.set(self.serv_ports[1]) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #启动按钮 self.start_serv_btn=Button(self,text=‘启动服务‘,command=self.start_serv) self.start_serv_btn.grid(row=3) #退出服务的按钮 self.start_exit_btn=Button(self,text=‘退出服务‘,command=self.root.destroy) self.start_exit_btn.grid(row=3,column=1) def get_ipaddr(self): #获取本机的ip地址 #获取名字 host_name=socket.gethostname() #获取信息 info=socket.gethostbyname_ex(host_name) info=info[2] info.append(self.local_ip) #定义启动服务器的方法 def start_serv(self): print(self.serv_ip.get(),self.serv_port.get()) start(self.serv_ip.get(),self.serv_port.get()) if __name__==‘__main__‘: root=Tk() root.title(‘备份服务器‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a=MyFrame(root) a.mainloop()
#coding=gbk from tkinter import * from tkinter.ttk import * import socket import os import struct import pickle #建立一个默认的备份目录 BAK_PATH=r‘e:\bak‘ #根据指定长度来接受文件信息 def recv_unit_data(clnt,infos_len): data=b‘‘ #原来文件为空 #如果要接受的文件在0-1024之间就直接接收该文件,如果大于1024需要循环分段接收,每次只是接收1024个字节,剩下的在全部接收即可 if 0<infos_len<=1024:# data+=clnt.recv(infos_len)#接收文件 else:#长度太长 while True: if infos_len >1024: data+=clnt.recv(1024) infos_len-=1024 else: data+=clnt.recv(infos_len) break return data def get_files_info(clnt): fmt_str=‘Q‘#用于向服务器端传送文件信息的大小 headsize=struct.calcsize(fmt_str)#计算长度 data=clnt.recv(headsize) infos_len=struct.unpack(fmt_str, data)[0] data =recv_unit_data(clnt, infos_len) return pickle.loads(data)#得到文件信息的列表 def mk_math(filepath): #建立文件路径 paths=filepath.split(os.path.sep)[:-1]#将文件路径进行分割 p=BAK_PATH for path in paths:#遍历用户端传来的路径 p=os.path.join(p,path)#将保存的路径添加到默认的路径上 if not os.path.exists(p):#如果路径不存在就建立路径 os.mkdir(p) #接收客户端传来文件,并且根据文件信息来进行保存备份 def recv_file(clnt,infos_len,filepath): mk_math(filepath)#遍历文件 通过路径 filepath = os.path.join(BAK_PATH,filepath)#服务器上的路径的文件名 f = open(filepath,‘wb+‘)#新建一个文件 #接收文件 try: if 0 < infos_len <=1024: data = clnt.recv(infos_len) f.write(data) else: while True: if infos_len >1024: data=clnt.recv(1024) f.write(data) infos_len-=1024 else: data = clnt.recv(infos_len) f.write(data) break except: print(‘error‘) else: return True finally: f.close() #向客户端发送失败成功消息 def send_echo(clnt,res): if res: clnt.sendall(b‘success‘) else: clnt.sendall(b‘failure‘) #启动服务器的方法 def start(host,port): if not os.path.exists(BAK_PATH): os.mkdir(BAK_PATH) st=socket.socket() #tcp协议 st.bind(host,port) #绑定套接字 st.listen(1) #侦听网络,一个客户端连接 client,addr=st.accept() #接收连接,建立连接 files_lst=get_files_info(client)#获取客户端要传送的文件列表(包括文件大小和文件路径:元组) for size,filepath in files_lst:#遍历得到文件大小和路径 res = recv_file(client,size,filepath)#接收所有的文件 返回备份的结果:true或者false send_echo(client,res)#保存成功标志,发送给客户端 client.close()#关闭客户端 st.close() def MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.local_ip=‘127.0.0.1‘#服务器端默认的IP地址 self.serv_ports=[10888,20888,30888]#三个服务器的端口 self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份服务器‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Combobox(self,values=self.get_ipaddr()) #设置默认的服务器的ip地址 self.serv_ip.set(self.local_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Combobox(self,values=self.serv_ports) #设置默认的服务端口 self.serv_port.set(self.serv_ports[1]) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #启动按钮 self.start_serv_btn=Button(self,text=‘启动服务‘,command=self.start_serv) self.start_serv_btn.grid(row=3) #退出服务的按钮 self.start_exit_btn=Button(self,text=‘退出服务‘,command=self.root.destroy) self.start_exit_btn.grid(row=3,column=1) def get_ipaddr(self): #获取本机的ip地址 #获取名字 host_name=socket.gethostname() #获取信息 info=socket.gethostbyname_ex(host_name) info=info[2] info.append(self.local_ip) #定义启动服务器的方法 def start_serv(self): print(self.serv_ip.get(),self.serv_port.get()) start(self.serv_ip.get(),int(self.serv_port.get())) if __name__==‘__main__‘: root=Tk() root.title(‘备份服务器‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a=MyFrame(root) a.mainloop()
#coding=gbk from tkinter import * from tkinter.ttk import * import socket import os import struct import pickle #建立一个默认的备份目录 BAK_PATH=r‘e:\bak‘ #根据指定长度来接受文件信息 def recv_unit_data(clnt,infos_len): data=b‘‘ #原来文件为空 #如果要接受的文件在0-1024之间就直接接收该文件,如果大于1024需要循环分段接收,每次只是接收1024个字节,剩下的在全部接收即可 if 0<infos_len<=1024:# data+=clnt.recv(infos_len)#接收文件 else:#长度太长 while True: if infos_len >1024: data+=clnt.recv(1024) infos_len-=1024 else: data+=clnt.recv(infos_len) break return data def get_files_info(clnt): fmt_str=‘Q‘#用于向服务器端传送文件信息的大小 headsize=struct.calcsize(fmt_str)#计算长度 data=clnt.recv(headsize) infos_len=struct.unpack(fmt_str, data)[0] data =recv_unit_data(clnt, infos_len) return pickle.loads(data)#得到文件信息的列表 def mk_math(filepath): #建立文件路径 paths=filepath.split(os.path.sep)[:-1]#将文件路径进行分割 p=BAK_PATH for path in paths:#遍历用户端传来的路径 p=os.path.join(p,path)#将保存的路径添加到默认的路径上 if not os.path.exists(p):#如果路径不存在就建立路径 os.mkdir(p) #接收客户端传来文件,并且根据文件信息来进行保存备份 def recv_file(clnt,infos_len,filepath): mk_math(filepath)#遍历文件 通过路径 filepath = os.path.join(BAK_PATH,filepath)#服务器上的路径的文件名 f = open(filepath,‘wb+‘)#新建一个文件 #接收文件 try: if 0 < infos_len <=1024: data = clnt.recv(infos_len) f.write(data) else: while True: if infos_len >1024: data=clnt.recv(1024) f.write(data) infos_len-=1024 else: data = clnt.recv(infos_len) f.write(data) break except: print(‘error‘) else: return True finally: f.close() #向客户端发送失败成功消息 def send_echo(clnt,res): if res: clnt.sendall(b‘success‘) else: clnt.sendall(b‘failure‘) #启动服务器的方法 def start(host,port): if not os.path.exists(BAK_PATH): os.mkdir(BAK_PATH) st=socket.socket() #tcp协议 st.bind((host,port)) #绑定套接字 st.listen(1) #侦听网络,一个客户端连接 client,addr=st.accept() #接收连接,建立连接 files_lst=get_files_info(client)#获取客户端要传送的文件列表(包括文件大小和文件路径:元组) for size,filepath in files_lst:#遍历得到文件大小和路径 res = recv_file(client,size,filepath)#接收所有的文件 返回备份的结果:true或者false send_echo(client,res)#保存成功标志,发送给客户端 client.close()#关闭客户端 st.close() class MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.local_ip=‘127.0.0.1‘#服务器端默认的IP地址 self.serv_ports=[10888,20888,30888]#三个服务器的端口 self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份服务器‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Combobox(self,values=self.get_ipaddr()) #设置默认的服务器的ip地址 self.serv_ip.set(self.local_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Combobox(self,values=self.serv_ports) #设置默认的服务端口 self.serv_port.set(self.serv_ports[1]) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #启动按钮 self.start_serv_btn=Button(self,text=‘启动服务‘,command=self.start_serv) self.start_serv_btn.grid(row=3) #退出服务的按钮 self.start_exit_btn=Button(self,text=‘退出服务‘,command=self.root.destroy) self.start_exit_btn.grid(row=3,column=1) def get_ipaddr(self): #获取本机的ip地址 #获取名字 host_name=socket.gethostname() #获取信息 info=socket.gethostbyname_ex(host_name) info=info[2] info.append(self.local_ip) #定义启动服务器的方法 def start_serv(self): print(self.serv_ip.get(),self.serv_port.get()) start(self.serv_ip.get(),int(self.serv_port.get())) if __name__==‘__main__‘: root=Tk() root.title(‘备份服务器‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a=MyFrame(root) a.mainloop() #coding=gbk from tkinter import * from tkinter.ttk import * import socket import os import pickle import struct #获取给出路径的文件信息 def get_file_info(path): if not path or not os.path.exists(path): return NONE files=os.walk(path)#获取文件 infos=[] file_paths=[] for p,d,fs in files:#文件都在fs列表中 for f in fs: file_name=os.path.join(p,f)#获取文件的文件名 file_size=os.stat(file_name).st_size#获取文件的大小 file_paths.append(file_name)#加入到file_path file_name=file_name[len(path)+1:] infos.append((file_size,file_name))#将文件信息加入到文件信息中 return infos,file_paths #向服务器端发送文件信息 def send_files_infos(my_sock,infos): fmt_str=‘Q‘ infos_bytes=pickle.dumps(infos)#对文件信息进行二进制编码 infos_bytes_len=len(infos_bytes)#获取长度 infos_len_pack=struct.pack(fmt_str,infos_bytes_len)#对长度利用struct进行二进制编码 my_sock.sendall(infos_len_pack)#将整个发送放到服务器端 my_sock.sendall(infos_bytes)#发送文件信息 def send_files(my_sock,file_path):#本机文件,本机文件路径 f = open(file_path,‘rb‘) try: while True: data=f.read(1024) if data: my_sock.sendall(data)#发送 else: break finally: f.close() def get_bak_info(my_sock,size=7): info = my_sock.recv(size) print(info.decode(‘utf-8‘)) def start(host,port,src): if not os.path.exists(src): print(‘备份的目标不存在!‘) return s = socket.socket()#TCP协议 s.connect((host,port)) path = src#获取用户的备份路径 file_infos,file_paths=get_file_info(path)#获取要备份的文件信息和路径 send_files_infos(s,file_infos)#发送文件信息 for fp in file_paths:#发送所有信息至S send_files(s,fp) print(fp)#把发送出去的文件的信息打印 get_bak_info(s)#获取备份的结果 s.close() class MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.remote_ip=‘127.0.0.1‘#服务器端的IP地址默认值 self.remote_ports=10888#默认的端口 self.remote_ip_var=StringVar()#输入框 self.remote_ports_var=IntVar() self.bak_src_var=StringVar() self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份客户端‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址:‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Entry(self,textvariable=self.remote_ip_var) #设置默认的服务器的ip地址e self.remote_ports_var.set(self.remote_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口:‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Entry(self,textvariable=self.remote_ports_var) #设置默认的服务端口 self.remote_ports_var.set(self.remote_ports) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #用户备份的数据 src_label=Label(self,text=‘备份的目标:‘) src_label.grid(row=3) #输入框 self.bak_src=Entry(self,textvariable=self.bak_src_var) self.bak_src.grid(row=3,column=1 ) # self.start_serv_btn=Button(self,text=‘开始备份‘,command=self.start_send) self.start_serv_btn.grid(row=4) # self.start_exit_btn=Button(self,text=‘退出程序‘,command=self.root.destroy) self.start_exit_btn.grid(row=4,column=1) #定义启动服务器的方法 def start_send(self): print(self.remote_ip_var.get(),self.remote_ports_var.get()) print(‘start...‘) start(self.remote_ip_var.get(),int(self.remote_ports_var.get()),self.bak_src_var.get())#想服务器发送东西 if __name__==‘__main__‘: root=Tk() root.title(‘远程备份客户机‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a = MyFrame(root) a.mainloop()
#coding=gbk from tkinter import * from tkinter.ttk import * import socket import threading import os import struct import pickle import threading #使用户图形界面和服务器退出循环变量 SERV_RUN_FLAG=TRUE flag_lock = threading.Lock() #建立一个默认的备份目录 BAK_PATH=r‘e:\bak‘ #根据指定长度来接受文件信息 def recv_unit_data(clnt,infos_len): data=b‘‘ #原来文件为空 #如果要接受的文件在0-1024之间就直接接收该文件,如果大于1024需要循环分段接收,每次只是接收1024个字节,剩下的在全部接收即可 if 0<infos_len<=1024:# data+=clnt.recv(infos_len)#接收文件 else:#长度太长 while True: if infos_len >1024: data+=clnt.recv(1024) infos_len-=1024 else: data+=clnt.recv(infos_len) break return data def get_files_info(clnt): fmt_str=‘Q?‘#用于向服务器端传送文件信息的大小,文件信息的压缩选项 headsize=struct.calcsize(fmt_str)#计算长度 data=clnt.recv(headsize) infos_len,compress=struct.unpack(fmt_str, data) data =recv_unit_data(clnt, infos_len) return pickle.loads(data),compress#得到文件信息的列表 def mk_math(filepath): #建立文件路径 paths=filepath.split(os.path.sep)[:-1]#将文件路径进行分割 p=BAK_PATH for path in paths:#遍历用户端传来的路径 p=os.path.join(p,path)#将保存的路径添加到默认的路径上 if not os.path.exists(p):#如果路径不存在就建立路径 os.mkdir(p) def get_compress_size(clnt): fmt_str = ‘Q‘#长整型 size=struct.calcsize(fmt_str) data = clnt.recv(size) size,=struct.unpack(fmt_str,data)#得到压缩后文件的大小 return size #接收客户端传来文件,并且根据文件信息来进行保存备份 def recv_file(clnt,infos_len,filepath,compress): mk_math(filepath)#遍历文件 通过路径 filepath = os.path.join(BAK_PATH,filepath)#服务器上的路径的文件名 #根据压缩选项判断 if compress : infos_len = get_compress_size(clnt)#压缩后文件的长度 filepath = ‘‘.join(os.path.splitext(filepath)[0],‘.tar.gz‘) f = open(filepath,‘wb+‘)#新建一个文件 #接收文件 try: if 0 < infos_len <=1024: data = clnt.recv(infos_len) f.write(data) else: while True: if infos_len >1024: data=clnt.recv(1024) f.write(data) infos_len-=1024 else: data = clnt.recv(infos_len) f.write(data) break except: print(‘error‘) else: return True finally: f.close() #向客户端发送失败成功消息 def send_echo(clnt,res): if res: clnt.sendall(b‘success‘) else: clnt.sendall(b‘failure‘) def client_operate(client): #compress 可压缩选项 files_lst,compress=get_files_info(client)#获取客户端要传送的文件列表(包括文件大小和文件路径:元组) for size,filepath in files_lst:#遍历得到文件大小和路径 res = recv_file(client,size,filepath,compress)#接收所有的文件 返回备份的结果:true或者false send_echo(client,res)#保存成功标志,发送给客户端 client.close()#关闭客户端 #启动服务器的方法 def start(host,port): if not os.path.exists(BAK_PATH): os.mkdir(BAK_PATH) st=socket.socket() #tcp协议 st.settimeout(1) #为了退出的时候能够有时间获得共享资源的锁,保证服务器端正常的退出;防止while中可以退出 st.bind((host,port)) #绑定套接字 st.listen(1) #侦听网络,一个客户端连接 #获得serv_run_falg的访问权 flag_lock.acquire() while SERV_RUN_FLAG:#多次服务 多线程 flag_lock.release()#释放访问权 client=None try: client,addr=st.accept() #接收连接,建立连接 #线程化的启动client_operater函数 防止当前进程正在执行的时候其他线程也要进程这个服务,所以我们就每次有客户端想要进行连接的时候,我们就创建一个线程去为每一个要求服务的东西提供服务 #多个服务器为多个客户端进行服务 except socket.timeout:#超时 pass if client: t =threading.Thread(target=client_operate,args=(client,)) t.start() flag_lock.acquire()#为了下次进入循环的时候仍然要锁定共享变量 st.close() class MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.local_ip=‘127.0.0.1‘#服务器端默认的IP地址 self.serv_ports=[10888,20888,30888]#三个服务器的端口 self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份服务器‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Combobox(self,values=self.get_ipaddr()) #设置默认的服务器的ip地址 self.serv_ip.set(self.local_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Combobox(self,values=self.serv_ports) #设置默认的服务端口 self.serv_port.set(self.serv_ports[1]) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #启动按钮 self.start_serv_btn=Button(self,text=‘启动服务‘,command=self.start_serv) self.start_serv_btn.grid(row=3) #退出服务的按钮 self.start_exit_btn=Button(self,text=‘退出服务‘,command=self.root.destroy) self.start_exit_btn.grid(row=3,column=1) def get_ipaddr(self): #获取本机的ip地址 #获取名字 host_name=socket.gethostname() #获取信息 info=socket.gethostbyname_ex(host_name) info=info[2] info.append(self.local_ip) #定义启动服务器的方法 def start_serv(self): #线程化运行 # print(self.serv_ip.get(),self.serv_port.get()) # start(self.serv_ip.get(),int(self.serv_port.get())) host = self.serv_ip.get()#获取服务器地址 port = int(self.serv_port.get())#获取服务端口,转化为整型 serv_th= threading.Thread(target=start,args=(host,port))#建立线程化服务器 serv_th.start() #当点击启动服务之后,我们关闭这个按钮不让服务再次启动 self.start_serv_btn.state([‘disabled‘,]) #建立一个自己的跟窗口的类,为了退出 class MyTk(Tk): def destroy(self): global SERV_RUN_FLAG while True: if flag_lock.acquire():#获取全局共享变量 SERV_RUN_FLAG=False flag_lock.release() break super().destroy() if __name__==‘__main__‘: root=MyTk() root.title(‘备份服务器‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a=MyFrame(root) a.mainloop() #coding=gbk from tkinter import * from tkinter.ttk import * import socket import os import pickle import struct import time import threading import tarfile,tempfile #获取给出路径的文件信息 def get_file_info(path): if not path or not os.path.exists(path): return NONE files=os.walk(path)#获取文件 infos=[] file_paths=[] for p,d,fs in files:#文件都在fs列表中 for f in fs: file_name=os.path.join(p,f)#获取文件的文件名 file_size=os.stat(file_name).st_size#获取文件的大小 file_paths.append(file_name)#加入到file_path file_name=file_name[len(path)+1:] infos.append((file_size,file_name))#将文件信息加入到文件信息中 return infos,file_paths #向服务器端发送文件信息 def send_files_infos(my_sock,infos,compress): fmt_str=‘Q?‘ infos_bytes=pickle.dumps(infos)#对文件信息进行二进制编码 infos_bytes_len=len(infos_bytes)#获取长度 infos_len_pack=struct.pack(fmt_str,infos_bytes_len,compress)#对长度利用struct进行二进制编码 my_sock.sendall(infos_len_pack)#将整个发送放到服务器端 my_sock.sendall(infos_bytes)#发送文件信息 def send_files(my_sock,file_path,compress):#本机文件,本机文件路径 if not compress: f = open(file_path,‘rb‘) else: f = tempfile.NamedTemporaryFile() tar=tarfile.open(mode=‘w|gz‘,fileobj=f) tar.add(file_path) tar.close() f.seek(0) filesize = os.stat(f.name).st_size filesize_bytes=struct.pack(‘Q‘, filesize) my_sock.sendall(filesize_bytes) try: while True: data=f.read(1024) if data: my_sock.sendall(data)#发送 else: break finally: f.close() def get_bak_info(my_sock,size=7): info = my_sock.recv(size) print(info.decode(‘utf-8‘)) def start(host,port,src,compress): if not os.path.exists(src): print(‘备份的目标不存在!‘) return s = socket.socket()#TCP协议 s.connect((host,port)) path = src#获取用户的备份路径 file_infos,file_paths=get_file_info(path)#获取要备份的文件信息和路径 send_files_infos(s,file_infos,compress)#发送文件信息 for fp in file_paths:#发送所有信息至S send_files(s,fp,compress) print(fp)#把发送出去的文件的信息打印 get_bak_info(s)#获取备份的结果 s.close() class MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.grid()#布局方式网格布局 self.remote_ip=‘127.0.0.1‘#服务器端的IP地址默认值 self.remote_ports=10888#默认的端口 self.remote_ip_var=StringVar()#输入框 self.remote_ports_var=IntVar() self.bak_src_var=StringVar() self.compress_var=BooleanVar() self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份客户端‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址:‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Entry(self,textvariable=self.remote_ip_var) #设置默认的服务器的ip地址e self.remote_ports_var.set(self.remote_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口:‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Entry(self,textvariable=self.remote_ports_var) #设置默认的服务端口 self.remote_ports_var.set(self.remote_ports) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #用户备份的数据 src_label=Label(self,text=‘备份的目标:‘) src_label.grid(row=3) #输入框 self.bak_src=Entry(self,textvariable=self.bak_src_var) self.bak_src.grid(row=3,column=1) tar_label=Label(self,text=‘备份压缩:‘) tar_label.grid(row =4 ) self.compress_on=Checkbutton(self,text=‘开始压缩‘,variable=self.compress_var,onvalue=1,offvalue=0) self.compress_on.grid(row=4,column=1) # self.start_serv_btn=Button(self,text=‘开始备份‘,command=self.start_send) self.start_serv_btn.grid(row=5) # self.start_exit_btn=Button(self,text=‘退出程序‘,command=self.root.destroy) self.start_exit_btn.grid(row=5,column=1) #定义启动服务器的方法 def start_send(self): # print(self.remote_ip_var.get(),self.remote_ports_var.get()) # print(‘start...‘) host = self.remote_ip_var.get() port = self.remote_ports_var.get() compress=self.compress_var.get() src=self.bak_src_var.get() self.bak_src_var.set(‘‘) t = threading.Thread(target=start,args=(host,int(port),src,compress)) t.start() # start(self.remote_ip_var.get(),int(self.remote_ports_var.get()),self.bak_src_var.get())#想服务器发送东西 if __name__==‘__main__‘: root=Tk() root.title(‘远程备份客户机‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a = MyFrame(root) a.mainloop()
#coding=gbk import socketserver import threading #关闭服务器 def sd(): if serv: serv.shutdown()#关闭服务器 #shutdown必须在serve_forever()不同线程中调用才能关闭服务器 class MyHdl(socketserver.StreamRequestHandler):#tcp协议的服务器 def handle(self):#覆盖handle方法 #和客户端进行交互 while True: data = self.request.recv(1024)#接收数据 print(‘收到数据:‘,data.decode(‘utf-8‘))#解码 if data==b‘bye‘: break self.request.sendall(data)#将收到的数据传回给客户端 print(‘本次服务结束‘) threading.Thread(target=sd).start() if __name__==‘__main__‘: HOST=‘‘ PORT=3214 #实例化TCPserver serv=socketserver.TCPServer((HOST,PORT),MyHdl)#服务的地址,自定义的类 #启动服务器 serv.serve_forever() #coding=gbk import socket HOST = ‘127.0.0.1‘ PORT = 3214 s=socket.socket()#tcp协议 s.connect((HOST,PORT)) data=‘你好‘ while data: #发送数据到服务器端 s.sendall(data.encode(‘utf_8‘)) if data==‘bye‘: break #从服务器端接收数据 data = s.recv(1024) print(‘收到数据;‘,data.decode(‘utf-8‘)) data=input(‘输入要发送的信息:‘) s.close()
#coding=gbk import socketserver class MyHdl(socketserver.StreamRequestHandler): def handle(self): while True: #从客户端读取一行数据 data = self.rfile.readline() if not data: break print(‘收到:‘,data.decode(‘utf-8‘.strip(‘\n‘)))#strip去除末尾的换行符 #把收到数据发回给客户端 self.wfile.write(data) if __name__==‘__main__‘: HOST = ‘‘ PORT = 3214 s = socketserver.TCPServer((HOST,PORT),MyHdl) s.serve_forever() #coding=gbk import socket HOST = ‘127.0.0.1‘ PORT = 3214 s=socket.socket()#tcp协议 s.connect((HOST,PORT)) data=‘你好‘ while data: #为了让服务器按行接收 data +=‘\n‘ s.sendall(data.encode(‘utf_8‘)) data = s.recv(1024) print(‘收到数据;‘,data.decode(‘utf-8‘).strip(‘\n‘))#strip 去除换行符 data=input(‘输入要发送的信息:‘) s.close()
#coding=gbk import socketserver class MyHdl(socketserver.DatagramRequestHandler): def handle(self): #UDP无连接的,从客户端获取字符和套接字 data,socket = self.request print(‘收到:‘,data.decode(‘utf-8‘.strip(‘\n‘)))#strip去除末尾的换行符 #把收到数据发回给客户端 socket.sendto(data,self.client_address) if __name__==‘__main__‘: HOST = ‘‘ PORT = 3214 s = socketserver.UDPServer((HOST,PORT),MyHdl) s.serve_forever() #coding=gbk import socket HOST = ‘127.0.0.1‘ PORT = 3214 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#UDP协议 data=‘你好‘ s.sendto(data.encode(‘utf-8‘),(HOST,PORT)) while data != ‘bye‘: data =b‘‘ while len(data)==0: data,addr=s.recvfrom(1024) print(‘收到数据;‘,data.decode(‘utf-8‘)) data=input(‘输入要发送的信息:‘) if data == ‘‘: data = ‘bye‘ s.sendto(data.encode(‘utf-8‘),(HOST,PORT)) s.close()
#coding=gbk from tkinter import * from tkinter.ttk import * import socket import threading import os import struct import pickle import threading import socketserver #建立一个默认的备份目录 BAK_PATH=r‘e:\bak‘ #根据指定长度来接受文件信息 def recv_unit_data(clnt,infos_len): data=b‘‘ #原来文件为空 #如果要接受的文件在0-1024之间就直接接收该文件,如果大于1024需要循环分段接收,每次只是接收1024个字节,剩下的在全部接收即可 if 0<infos_len<=1024:# data+=clnt.recv(infos_len)#接收文件 else:#长度太长 while True: if infos_len >1024: data+=clnt.recv(1024) infos_len-=1024 else: data+=clnt.recv(infos_len) break return data def get_files_info(clnt): fmt_str=‘Q?‘#用于向服务器端传送文件信息的大小,文件信息的压缩选项 headsize=struct.calcsize(fmt_str)#计算长度 data=clnt.recv(headsize) infos_len,compress=struct.unpack(fmt_str, data) data =recv_unit_data(clnt, infos_len) return pickle.loads(data),compress#得到文件信息的列表 def mk_math(filepath): #建立文件路径 paths=filepath.split(os.path.sep)[:-1]#将文件路径进行分割 p=BAK_PATH for path in paths:#遍历用户端传来的路径 p=os.path.join(p,path)#将保存的路径添加到默认的路径上 if not os.path.exists(p):#如果路径不存在就建立路径 os.mkdir(p) def get_compress_size(clnt): fmt_str = ‘Q‘#长整型 size=struct.calcsize(fmt_str) data = clnt.recv(size) size,=struct.unpack(fmt_str,data)#得到压缩后文件的大小 return size #接收客户端传来文件,并且根据文件信息来进行保存备份 def recv_file(clnt,infos_len,filepath,compress): mk_math(filepath)#遍历文件 通过路径 filepath = os.path.join(BAK_PATH,filepath)#服务器上的路径的文件名 #根据压缩选项判断 if compress : infos_len = get_compress_size(clnt)#压缩后文件的长度 filepath = ‘‘.join(os.path.splitext(filepath)[0],‘.tar.gz‘) f = open(filepath,‘wb+‘)#新建一个文件 #接收文件 try: if 0 < infos_len <=1024: data = clnt.recv(infos_len) f.write(data) else: while True: if infos_len >1024: data=clnt.recv(1024) f.write(data) infos_len-=1024 else: data = clnt.recv(infos_len) f.write(data) break except: print(‘error‘) else: return True finally: f.close() #向客户端发送失败成功消息 def send_echo(clnt,res): if res: clnt.sendall(b‘success‘) else: clnt.sendall(b‘failure‘) def client_operate(client): #compress 可压缩选项 files_lst,compress=get_files_info(client)#获取客户端要传送的文件列表(包括文件大小和文件路径:元组) for size,filepath in files_lst:#遍历得到文件大小和路径 res = recv_file(client,size,filepath,compress)#接收所有的文件 返回备份的结果:true或者false send_echo(client,res)#保存成功标志,发送给客户端 client.close()#关闭客户端 #建立服务器 class BakHdl(socketserver.StreamRequestHandler): def handle(self): client_operate(self.request) #建立服务器和启动服务器 def start(host,port): #初始化 server = socketserver.ThreadingTCPServer((host,port),BakHdl) #线程的方法启动服务器 s = threading.Thread(target=server.serve_forever) s.start() return server class MyFrame(Frame): #初始化构造方法 def __init__(self,root): super().__init__(root) self.root=root self.server = None self.grid()#布局方式网格布局 self.local_ip=‘127.0.0.1‘#服务器端默认的IP地址 self.serv_ports=[10888,20888,30888]#三个服务器的端口 self.init_components()#初始化界面方法 #界面函数的实现 def init_components(self):#初始化用户界面的方法 proj_name=Label(self,text=‘远程备份服务器‘) proj_name.grid(columnspan=2)#网格式布局,占用两列 serve_ip_label=Label(self,text=‘服务地址‘) serve_ip_label.grid(row=1)#列是默认为0列 #下拉列表,显示服务器的地址拱用户选择 self.serv_ip=Combobox(self,values=self.get_ipaddr()) #设置默认的服务器的ip地址 self.serv_ip.set(self.local_ip) self.serv_ip.grid(row=1,column=1) #服务端口的LABEL serv_port_label=Label(self,text=‘服务端口‘) serv_port_label.grid(row=2) #下拉列表,显示服务器的服务端口拱用户选择 self.serv_port=Combobox(self,values=self.serv_ports) #设置默认的服务端口 self.serv_port.set(self.serv_ports[1]) #网格布局 放置指定位置 self.serv_port.grid(row=2,column=1) #启动按钮 self.start_serv_btn=Button(self,text=‘启动服务‘,command=self.start_serv) self.start_serv_btn.grid(row=3) #退出服务的按钮 self.start_exit_btn=Button(self,text=‘退出服务‘,command=self.exit)#退出服务关闭图形界面 self.start_exit_btn.grid(row=3,column=1) def exit(self): if self.server: threading.Thread(target=self.server.shutdown).start()#启动关闭服务器的线程 self.root.destroy() def get_ipaddr(self): #获取本机的ip地址 #获取名字 host_name=socket.gethostname() #获取信息 info=socket.gethostbyname_ex(host_name) info=info[2] info.append(self.local_ip) #定义启动服务器的方法 def start_serv(self): if not os.path.exists(BAK_PATH): os.mkdir(BAK_PATH) # print(self.serv_ip.get(),self.serv_port.get()) # start(self.serv_ip.get(),int(self.serv_port.get())) host = self.serv_ip.get()#获取服务器地址 port = int(self.serv_port.get())#获取服务端口,转化为整型 self.server = start(host,port) # serv_th= threading.Thread(target=start,args=(host,port))#建立线程化服务器 # serv_th.start() # #当点击启动服务之后,我们关闭这个按钮不让服务再次启动 self.start_serv_btn.state([‘disabled‘,]) if __name__==‘__main__‘: root=Tk() root.title(‘备份服务器‘) root.resizable(FALSE, FALSE)#允许用户更改窗体大小 a=MyFrame(root) a.mainloop()
#coding=gbk import socket import socketserver import threading import time import os #requesthandler类 class FTPHdl(socketserver.StreamRequestHandler): def __init__(self,request=None,client_address=None,server=None): self.coms_keys = (‘QUIT‘,‘USER‘,‘NOOP‘,‘TYPE‘,‘PASV‘,‘PORT‘,‘RETP‘,‘STOR‘) #建立命令所对应的方法 self.coms={} # self.init_coms() self.server #服务器命令模块的端口 self.cmd_port=21 #数据模块端口 self.data_port=20 #保存ip地址和端口号 self.pasv_data_ip=None self.pasv_data_port=None self.args=None self.loged=False #模式 self.pasv_mode=None super().__init__(request, client_address, server) #字典方法 命令 def init_coms(self): for k in self.coms_keys: self.coms[k]=getattr(self,‘exe_‘ + k.lower())#获取当前类的方法 exe为前缀,lower为命令的小写 #用于对客户单进行处理 def handle(self): while True: #接收用户端命令,读取一行 cmds = self.rfile.readline() if not cmds: continue cmds = cmds.decode(‘utf-8‘) #建立命令动词 命令行的分析 cmd = self.deal_args(cmds) if cmd in self.coms_keys:#命令动词是否在ftp所有的命令中 self.coms.get(cmd)() else: #返回错误代码 self.send(500,‘Invaild command.‘) #如果命令为退出 if cmd == ‘QUIT‘: break #分析命令信息 def deal_args(self,cmds): #如果空格在命令行中 必须分开 前面是命令动词 后面是命令参数 if ‘ ‘ in cmds: cmd,args=cmds.split(‘ ‘) args = args.strip(‘\n‘).strip()#对参数进行处理 else: cmd=cmds.strip(‘\n‘)#删除换行符 args=‘‘ if args: self.args=args return cmd.upper()#返回命令动词 大写 def exe_quit(self): self.send(221,‘bye‘) def exe_user(self): user=self.args if user in (‘‘,‘anonymous‘): user = ‘annoymous‘ self.loged=True self.send(230,‘identified!‘) else: self.send(530,‘Only use annoymous‘) def exe_pasv(self): if not self.loged: self.send(332,‘Please login.‘) return if self.pasv_mode: info = ‘entering passive mode (%s)‘ % self.make_pasv_info() self.send(227,info) return try: self.enter_pasv() info = ‘entering passive mode (%s)‘ %self.make_pasv_info() self.pasv_mode=True self.send(227,info) except Exception as e: print(e) self.send(500,‘failure change to passive mode.‘) def enter_pasv(self): if self.server.data_server is None: self.pasv_data_ip,self.pasv_data_port=self.server.create_data_server() def exe_port(self): self.send(500,‘Do not offer port mode.‘) def exe_noop(self): self.send(200,‘ok‘) def exe_type(self): self.send(200,‘ok‘) def exe_retr(self): if not os.path.exists(self.args): self.send(550,‘File is not exists.‘) return client_addr=self.request.getpeername()[0] self.add_opr_file(client_addr,(‘RETR‘,self.args)) self.send(150,‘ok.‘) def exe_stor(self): client_addr=self.request.getpeername()[0] self.add_opr_file(client_addr,(‘STOP‘,self.args)) def add_opr_file(self,client_addr,item): if client_addr in DataHdl.client_opr: DataHdl.client_opr[client_addr].append(item) else: DataHdl.client_opr[client_addr]=[item,] def sebd(self,code,info): infos=‘%d %s\n‘ % (code,info) self.request.sendall(infos.encode(‘utf_8‘)) class MyThrTCPServ(socketserver.ThreadingTCPServer): def __init__(self,addr,Hdl): self.data_server=None super().__init__(addr,Hdl) def shutdown(self): if self.data_server: threading.Thread(target=self.data_server.shutdown).start() super().shutdown() def create_data_server(self): self.data_server=socketserver.ThreadingTCPServer((‘127.0.0.1‘,0),DataHdl) pasv_data_ip,pasv_data_port=self.data_server.server_address threading.Thread(target=self.data_server.serve_forever).start() return pasv_data_ip,pasv_data_port class DataHdl(socketserver.StreamRequestHandler): client_opr={} def handle(self): peerip=self.request.getpeername()[0] opr=self.get_opr_args(peerip) if opr: if opr[0]==‘RETR‘: self.retr_file(opr[1]) elif opr[0]==‘STOR‘: self.stor_file(opr[1]) self.request.close() def get_opr_args(self,peerip): if peerip in self.client_opr: opr= self.client_opr[peerip].pop(0) if not self.client_opr[peerip]: self.client_opr.pop(peerip) return opr def retr_file(self,filepath): f = open(filepath,‘rb‘) while True: data = f.read(1024) if data: self.request.sendall(data) else: break f.close() def stor_file(self,filepath): f=open(os.path.join(‘.‘,‘baket‘,filepath),‘wb‘) while True: data =self.request.recv(1024) if data: f.write(data) else: break f.close() if __name__==‘__main__‘: server = MyThrTCPServ((‘127.0.0.1‘,21),FTPHdl) threading.Thread(target=server.serve_forever).start() print(‘FTP start...‘) time.sleep(30) server.shutdown() #coding=gbk import os import socket import threading import socketserver def get_file(host,port,filepath): s=socket.socket() s.connect((host,port)) filepath=os.path.join(‘.‘,‘bakt‘,filepath) f=open(filepath,‘wb‘) data = True while data: data=s.recv(1024) if data: f.write(data) s.close() f.close() def put_file(host,port,filepath): s=socket.socket() s.connect((host,port)) f=open(filepath,‘rb‘) while true: data=f.read(1024) if data: s.sendall(data) else: break s.close() f.close() class FtpClient: def __init__(self,host=‘localhost‘,port=21): self.host=host self.port=port self.cmds=(‘QUIT‘,‘USER‘,‘NOOP‘,‘TYPE‘,‘PASV‘,‘PORT‘,‘RETP‘,‘STOR‘) self.linesep=‘\n‘ self.data_port=None self.loged=False self.sock=None self.pasv_mode=None self.pasv_host=None self.pasv_port=None def cmd_connect(self): self.sock=socket.socket() self.sock.connect((self.host,self.port)) self.data_port=self.sock.getsockname()[0] def start(self): print(‘支持的命令:‘,self.cmds) self.cmd_connect() self.login() while True: cmd=input(‘请输入FTP命令: ‘) if not cmd: print(‘FTP命令不能为空。‘) continue cmd,args=self.split_args(cmd) if not self.send_cmd(cmd,args): continue res = self.readline(self.sock) print(res) if cmd.stratswith(‘PASV‘) and res.startswith(‘227‘): self.pasv_mode=True servinfo =res[res.index(‘(‘)+1:res.index(‘)‘)] self.pasv_host=‘.‘.join(servinfo.split(‘,‘)[:4]) servinfo =servinfo.split(‘,‘)[-2:] self.pasv_port=256*int(servinfo[0])+int(servinfo[1]) if cmd.startswith(‘RETR‘): if self.pasv_mode: threading.Thread(target=get_file,args=(self.pasv_host,self.pasv_port,args)).start() if cmd.startswith(‘STOR‘): if self.pasv_mode: threading.Thread(target=put_file,args=(self.pasv_host,self.pasv_port,args)).start() if cmd.startswith(‘QUIT‘): break self.sock.close() self.sock=None def login(self): if self.sock: self.send_cmd(‘USER‘) res=self.readline(self.sock) if res.startswith(‘230‘): print(‘登录成功!‘) self.loged def readline(self,sock): data = ‘‘ while not data.endswith(self.linesep): d=sock.recv(1) data +=d.decode(‘utf-8‘) return data def split_args(self,cmds): if ‘ ‘ in cmds: cmdlsts = cmds.split(‘ ‘) cmd = cmdlsts[0] args=‘ ‘.join(cmdlsts[1:]) else: cmd = cmds args = ‘‘ return cmd.upper(),args def send_cmd(self,cmd,args=‘‘): if self.sock: if args: cmd = ‘ ‘.join((cmd,args)) if cmd.startswith(‘RETR‘) or cmd.startswith(‘STOR‘): if self.pasv_mode is None: print(‘Please appoint port or stor mode.‘) return False if not args: return False if cmd.startswith(‘STOR‘): if args: if not os.path.exists(args): print(‘File is not exists‘) return False cmd+=self.linesep self.sock.sendall(cmd.encode(‘utf-8‘)) return True if __name__==‘__main__‘: fc=FtpClient() fc.start()
标签:
原文地址:http://www.cnblogs.com/Kobe10/p/5714622.html