ABKYH 发表于 2018-8-9 13:05:13

python之SocketServer传文件实例

  一、socket传文件实例1:

  Sever
#!/usr/bin/python27  #coding:utf-8
  import SocketServer
  import os
  class myserver(SocketServer.BaseRequestHandler):
  def handle(self):
  #print(self.request,self.client_address,self.server)
  base_path = '/root/test/python27/socket/'
  conn = self.request
  print('connected...')
  while True:
  pre_data = conn.recv(1024)
  file_name,file_size = pre_data.split('|')
  recv_size = 0
  file_dir = os.path.join(base_path,file_name)
  conn.sendall('请传输正文')
  f = open(file_dir,'wb')
  print(file_size)
  flag = True
  while flag:
  if int(file_size) > recv_size:
  data = conn.recv(1024)
  recv_size += len(data)
  else:
  break
  f.write(data)
  print('upload successed')
  f.close()
  print('传输完成')
  if __name__ == '__main__':
  instance = SocketServer.ThreadingTCPServer(('0.0.0.0',9999),myserver)
  instance.serve_forever()

  Client
#!/usr/bin/env python  #coding:utf-8
  import socket
  import sys
  import os
  ip_port = ('127.0.0.1',9999)
  sk = socket.socket()
  sk.connect(ip_port)
  while True:
  name = raw_input('please input the file path:')
  file_name = os.path.basename(name)
  file_size = os.stat(name).st_size
  sk.sendall(file_name + '|' + str(file_size))
  data = sk.recv(1024)
  print(data)
  send_size = 0
  f = open(name,'rb')
  Flag = True
  while Flag:
  if send_size + 1024 >file_size:
  data = f.read(file_size-send_size)
  Flag = False
  else:
  data = f.read(1024)
  send_size+=1024
  sk.send(data)
  f.close()
  sk.close()
  二、socket传文件实例2:
  用一种编程语言实现一个简单的Server/Client程序;该程序的主要功能是利用Client从Server端下载一个文件;在下载之前,需要有一定的用户身份验证机制(说白了就是先输入以下用户名和密码);Server应该是多线程机制的,即为每个Client请求Server都要有一个线程去处理,而不是所有的Client都是一个Server线程处理。
  处理流程:

[*]  1、server启动,监听client请求;
[*]  2、client启动;
[*]  3、server监听到client,发送“Hi”;
[*]  4、client收到“Hi”
[*]  5、client要求用户输入用户名;
[*]  6、用户输入用户名(如yangsq),发送到服务器(形式为“username:yangsq”);
[*]  7、服务器验证是否存在这样一个用户,如果有到step 8,否则转到5;
[*]  8、client用求用户输入密码(如123456),发送到服务器(形式为“password:123456”);
[*]  9、服务器验证密码是否正确,不正确转到step 8,正确开始传输文件(为了简单,文件预先指定好);
[*]  10、client收到文件,结束后发送“EOF”;同时server端收到“EOF”后结束线程。
  服务端:
  #!/usr/bin/python27
  #coding:utf-8
  import SocketServer
  import time
  import os
  class MyTcpServer(SocketServer.BaseRequestHandler):
  userInfo = {
  'wang':'wang',
  'kai':'kai',
  'kevin':'kevin' }
  def recvfile(self, filename):
  name = os.path.basename(filename)
  print("starting recv file <%s> ..." % filename)
  f = open(name, 'wb')
  self.request.send('ready')
  while True:
  data = self.request.recv(4096)
  if data == 'EOF':
  print "recv file success!"
  break
  f.write(data)
  f.close()
  def sendfile(self, filename):
  if os.path.isfile(filename):
  print("starting send file <%s> ..." % filename)
  self.request.send('ready')
  time.sleep(1)
  f = open(filename, 'rb')
  while True:
  data = f.read(4096)
  if not data:
  break
  self.request.send(data)
  f.close()
  time.sleep(1)
  self.request.send('EOF')
  print("send file success!")
  else:
  print("the file <%s> is not exist" % filename)
  self.request.send("the file <%s> is not exist" % filename)
  def handle(self):
  print("get connection from :",self.client_address)
  while True:
  try:
  data = self.request.recv(1024)
  print(data)
  if not data:
  print("break the connection!")
  break
  elif data == 'Hi, server':
  self.request.sendall('hi, client')
  elif data.startswith('name'):
  self.clientName = data.split(':')[-1]
  if self.userInfo.has_key(self.clientName):
  self.request.sendall('valid')
  else:
  self.request.sendall('invalid')
  elif data.startswith('pwd'):
  self.clientPwd = data.split(':')[-1]
  if self.clientPwd == self.userInfo:
  self.request.sendall('valid')
  time.sleep(5)
  while True:
  file_data = self.request.recv(1024)
  if file_data == 'exit':
  break
  action, filename = file_data.split()
  if action == "put":
  self.recvfile(filename)
  elif action == 'get':
  self.sendfile(filename)
  else:
  print("the action <%s> is error !" % action)
  else:
  self.request.sendall('invalid')
  else:
  self.request.sendall('请重新输入')
  except Exception,e:
  print("get error at:",e)
  if __name__ == "__main__":
  host = '0.0.0.0'
  port = 6000
  s = SocketServer.ThreadingTCPServer((host,port), MyTcpServer)
  s.serve_forever()
  客户端:
#!/usr/bin/python27  #coding:utf-8
  import socket
  import sys,os
  import time
  def recvfile(filename):
  print "server ready, now client recv file~~"
  name = os.path.basename(filename)
  f = open(name, 'wb')
  while True:
  data = s.recv(4096)
  if data == 'EOF':
  print "recv file success!"
  break
  f.write(data)
  f.close()
  def sendfile(filename):
  print "server ready, now client send file~~"
  f = open(filename, 'rb')
  while True:
  data = f.read(4096)
  if not data:
  break
  s.sendall(data)
  f.close()
  time.sleep(1)
  s.sendall('EOF')
  print "send file success!"
  def confirm(s, client_command):
  s.send(client_command)
  confirm_data = s.recv(1024)
  print(confirm_data)
  if confirm_data == 'ready':
  return True
  else:
  return False
  def auth_user():
  name = raw_input('Server: input our name:')
  s.sendall('name:' + name.strip())
  response = s.recv(1024)
  if response == 'valid':
  res = False
  while not res:
  res = auth_pass()
  return True
  else:
  return False
  def auth_pass():
  pwd = raw_input('Server: input our password:')
  s.sendall('pwd:' + pwd.strip())
  response = s.recv(1024)
  if response == 'valid':
  return True
  else:
  return False
  ############################main##############################
  ip = '127.0.0.1'
  port = 6000
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  try:
  s.connect((ip,port))
  s.sendall('Hi, server')
  res = s.recv(1024)
  print(res)
  while True:
  result = auth_user()
  if result:
  while True:
  select = raw_input("Server: Do you want put/get the file from the server?(y/n):")
  if select =='y':
  client_command = raw_input("method:put/get filename:")
  if not client_command:
  continue
  elif client_command == 'exit':
  s.sendall('exit')
  sys.exit('退出')
  action, filename = client_command.split()
  if action == 'put':
  if os.path.isfile(filename):
  if confirm(s, client_command):
  sendfile(filename)
  else:
  print("the file <%s> is not exist" % filename)
  elif action == 'get':
  if confirm(s, client_command):
  recvfile(filename)
  else:
  print("command error!")
  else:
  s.sendall('exit')
  sys.exit('传输完成,正常退出')
  except socket.error,e:
  print "get error as",e
  finally:
  s.close()
  python的网络编程确实简单,因为它提供了各种功能的已经写好的类,直接继承就Ok了。
页: [1]
查看完整版本: python之SocketServer传文件实例