python之SocketServer传

发布时间:2019-09-06 08:57:53编辑:auto阅读(1516)

    一、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了。


关键字