`
yangsq
  • 浏览: 181006 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用python实现的简单Server/Client文件传输

阅读更多

还是那个题目(题目和流程见java版本),感觉光用java写一点新意也没有,恰巧刚学习了python,何不拿来一用,呵呵:

服务器端:

python 代码
  1. import SocketServertime  
  2.   
  3. class MyServer(SocketServer.BaseRequestHandler):   
  4.     userInfo = {   
  5.         'yangsq'    : 'yangsq',   
  6.         'hudeyong'  : 'hudeyong',   
  7.         'mudan'     : 'mudan' }   
  8.   
  9.     def handle(self):   
  10.         print 'Connected from', self.client_address   
  11.            
  12.         while True:   
  13.             receivedData = self.request.recv(8192)   
  14.             if not receivedData:   
  15.                 continue  
  16.                
  17.             elif receivedData == 'Hi, server':   
  18.                 self.request.sendall('hi, client')   
  19.                    
  20.             elif receivedData.startswith('name'):   
  21.                 self.clientName = receivedData.split(':')[-1]   
  22.                 if MyServer.userInfo.has_key(self.clientName):   
  23.                     self.request.sendall('valid')   
  24.                 else:   
  25.                     self.request.sendall('invalid')   
  26.                        
  27.             elif receivedData.startswith('pwd'):   
  28.                 self.clientPwd = receivedData.split(':')[-1]   
  29.                 if self.clientPwd == MyServer.userInfo[self.clientName]:   
  30.                     self.request.sendall('valid')   
  31.                     time.sleep(5)   
  32.   
  33.                     sfile = open('PyNet.pdf', 'rb')   
  34.                     while True:   
  35.                         data = sfile.read(1024)   
  36.                         if not data:   
  37.                             break  
  38.                         while len(data) > 0:   
  39.                             intSent = self.request.send(data)   
  40.                             data = data[intSent:]   
  41.   
  42.                     time.sleep(3)   
  43.                     self.request.sendall('EOF')   
  44.                 else:   
  45.                     self.request.sendall('invalid')   
  46.                        
  47.             elif receivedData == 'bye':   
  48.                 break  
  49.   
  50.         self.request.close()   
  51.            
  52.         print 'Disconnected from', self.client_address   
  53.         print  
  54.   
  55. if __name__ == '__main__':   
  56.     print 'Server is started\nwaiting for connection...\n'   
  57.     srv = SocketServer.ThreadingTCPServer(('localhost', 50000), MyServer)   
  58.     srv.serve_forever()              

说明:

  • line-55到line-58的作用就相当于java中某个类里面的main函数,即一个类的入口。
  • python中SocketServer module里提供了好多实用的现成的类,BaseRequestHandler就是一个,它的作用是为每一个请求fork一个线程,只要继承它,就有这个能力了,哈哈,真是美事。
  • 当然,我们继承了BaseRequestHandler,就是override它的handle方法,就像java中继承了Thread后要实现run方法一样。实际上这个handle方法的内容和我们的java版本的run函数实现的完全一样。
  • line-30到line-43就是处理文件下载的主要内容了。看着都挺眼熟的呵:)
  • 这里在文件发送完后发了一个“EOF”,告诉client文件传完了。

客户端:

python 代码
  1. import sockettime  
  2.   
  3. class MyClient:   
  4.   
  5.     def __init__(self):   
  6.         print 'Prepare for connecting...'   
  7.   
  8.     def connect(self):   
  9.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   
  10.         sock.connect(('localhost', 50000))   
  11.   
  12.         sock.sendall('Hi, server')   
  13.         self.response = sock.recv(8192)   
  14.         print 'Server:', self.response   
  15.   
  16.         self.s = raw_input("Server: Do you want get the 'thinking in python' file?(y/n):")   
  17.         if self.s == 'y':   
  18.             while True:   
  19.                 self.name = raw_input('Server: input our name:')   
  20.                 sock.sendall('name:' + self.name.strip())   
  21.                 self.response = sock.recv(8192)   
  22.                 if self.response == 'valid':   
  23.                     break  
  24.                 else:   
  25.                     print 'Server: Invalid username'   
  26.   
  27.             while True:   
  28.                 self.pwd = raw_input('Server: input our password:')   
  29.                 sock.sendall('pwd:' + self.pwd.strip())   
  30.                 self.response = sock.recv(8192)   
  31.                 if self.response == 'valid':   
  32.                     print 'please wait...'   
  33.   
  34.                     f = open('b.pdf', 'wb')   
  35.                     while True:   
  36.                         data = sock.recv(1024)   
  37.                         if data == 'EOF':   
  38.                             break  
  39.                         f.write(data)   
  40.                            
  41.                     f.flush()   
  42.                     f.close()   
  43.   
  44.                     print 'download finished'   
  45.                     break  
  46.                 else:   
  47.                     print 'Server: Invalid password'   
  48.                    
  49.   
  50.         sock.sendall('bye')   
  51.         sock.close()   
  52.         print 'Disconnected'   
  53.   
  54. if __name__ == '__main__':   
  55.     client = MyClient()   
  56.     client.connect()   

line-34到line-41处理文件下载,client收到server的“EOF”信号后,就知道文件传完了。

最后需要说明一下python的文件,由于是内置类型,所以不想java那样有那么多的reader,writer,input,ouput啊。python中,在打开或建立一个文件时,主要是通过模式(mode)来区别的。

python的网络编程确实简单,因为它提供了各种功能的已经写好的类,直接继承就Ok了。

python还在学习中,上面的例子跑通是没问题,但写得肯定不够好,还得学习啊

分享到:
评论
3 楼 yangsq 2007-10-09  
Thanks, i've changed it
2 楼 mathgl 2007-10-08  
receivedData = self.request.recv(8192)   
            if not receivedData:   
                continue  

这里的 if not receiveData:
其实并不需要
如果你的socket是block的 在recv那里会一直等待(block)
直到有一些数据到达为止
1 楼 mathgl 2007-10-08  
我也写了几个类似的程序
是公司用来传输文件用的

基本上差不多 差别在于其中一个用 socket
另外一个用twisted罢了

相关推荐

Global site tag (gtag.js) - Google Analytics