Python实现的简单文件传输服务器和客户端
还是那个题目(题目和流程见java版本),感觉光用java写一点新意也没有,恰巧刚学习了python,何不拿来一用,呵呵:
服务器端:
importSocketServer,time classMyServer(SocketServer.BaseRequestHandler): userInfo={ 'yangsq':'yangsq', 'hudeyong':'hudeyong', 'mudan':'mudan'} defhandle(self): print'Connectedfrom',self.client_address whileTrue: receivedData=self.request.recv(8192) ifnotreceivedData: continue elifreceivedData=='Hi,server': self.request.sendall('hi,client') elifreceivedData.startswith('name'): self.clientName=receivedData.split(':')[-1] ifMyServer.userInfo.has_key(self.clientName): self.request.sendall('valid') else: self.request.sendall('invalid') elifreceivedData.startswith('pwd'): self.clientPwd=receivedData.split(':')[-1] ifself.clientPwd==MyServer.userInfo[self.clientName]: self.request.sendall('valid') time.sleep(5) sfile=open('PyNet.pdf','rb') whileTrue: data=sfile.read(1024) ifnotdata: break whilelen(data)>0: intSent=self.request.send(data) data=data[intSent:] time.sleep(3) self.request.sendall('EOF') else: self.request.sendall('invalid') elifreceivedData=='bye': break self.request.close() print'Disconnectedfrom',self.client_address print if__name__=='__main__': print'Serverisstarted\nwaitingforconnection...\n' srv=SocketServer.ThreadingTCPServer(('localhost',50000),MyServer) srv.serve_forever()
说明:
line-55到line-58的作用就相当于java中某个类里面的main函数,即一个类的入口。
python中SocketServermodule里提供了好多实用的现成的类,BaseRequestHandler就是一个,它的作用是为每一个请求fork一个线程,只要继承它,就有这个能力了,哈哈,真是美事。
当然,我们继承了BaseRequestHandler,就是override它的handle方法,就像java中继承了Thread后要实现run方法一样。实际上这个handle方法的内容和我们的java版本的run函数实现的完全一样。
line-30到line-43就是处理文件下载的主要内容了。看着都挺眼熟的呵:)
这里在文件发送完后发了一个“EOF”,告诉client文件传完了。
客户端:
importsocket,time classMyClient: def__init__(self): print'Prepareforconnecting...' defconnect(self): sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect(('localhost',50000)) sock.sendall('Hi,server') self.response=sock.recv(8192) print'Server:',self.response self.s=raw_input("Server:Doyouwantgetthe'thinkinginpython'file?(y/n):") ifself.s=='y': whileTrue: self.name=raw_input('Server:inputourname:') sock.sendall('name:'+self.name.strip()) self.response=sock.recv(8192) ifself.response=='valid': break else: print'Server:Invalidusername' whileTrue: self.pwd=raw_input('Server:inputourpassword:') sock.sendall('pwd:'+self.pwd.strip()) self.response=sock.recv(8192) ifself.response=='valid': print'pleasewait...' f=open('b.pdf','wb') whileTrue: data=sock.recv(1024) ifdata=='EOF': break f.write(data) f.flush() f.close() print'downloadfinished' break else: print'Server:Invalidpassword' sock.sendall('bye') sock.close() print'Disconnected' if__name__=='__main__': client=MyClient() client.connect()
line-34到line-41处理文件下载,client收到server的“EOF”信号后,就知道文件传完了。
最后需要说明一下python的文件,由于是内置类型,所以不想java那样有那么多的reader,writer,input,ouput啊。python中,在打开或建立一个文件时,主要是通过模式(mode)来区别的。
python的网络编程确实简单,因为它提供了各种功能的已经写好的类,直接继承就Ok了。
python还在学习中,上面的例子跑通是没问题,但写得肯定不够好,还得学习啊