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还在学习中,上面的例子跑通是没问题,但写得肯定不够好,还得学习啊