python之SocketServer传

2023-01-31 05:01:44 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. 1、server启动,监听client请求;

  2. 2、client启动;

  3. 3、server监听到client,发送“Hi”;

  4. 4、client收到“Hi”

  5. 5、client要求用户输入用户名;

  6. 6、用户输入用户名(如yangsq),发送到服务器(形式为“username:yangsq”);

  7. 7、服务器验证是否存在这样一个用户,如果有到step 8,否则转到5;

  8. 8、client用求用户输入密码(如123456),发送到服务器(形式为“passWord:123456”);

  9. 9、服务器验证密码是否正确,不正确转到step 8,正确开始传输文件(为了简单,文件预先指定好);

  10. 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.clientName]:   
                        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了。


相关文章