zoukankan      html  css  js  c++  java
  • 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天

     由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的

     

    项目一:用socket实现文件传输

    本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket进行项目开发,难不倒各位

     

    项目要求:

    1.用socket完成文件上传功能

    2.文件位置可以设置

    3.传输协议可以为get,和post

    4.路径存放位置可以设置

    5.服务端实现多用户连接,客户端随意

     

    要求就这么简单,好久没有这么简单的操作了吧?

     

    不多说,直接来。

    程序结构:

     

    settings.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    # datetime:2018/2/11 0011 22:18
    
    import os
    
    base_dir = os.path.dirname(__file__)    #默认根目录
    transport_type = 'post'                 #传输方式
    dir = 'test'                            #存放文件夹名,记得事先创建好
    path = os.path.join(base_dir,dir)       #存放路径
    

     

    pic_server.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:yangva
    
    
    import socket,os
    import settings
    
    s = socket.socket()
    address = ('127.0.0.1',8800)
    s.bind(address)
    s.listen(3)
    base_dir = settings.base_dir
    
    def recv():
        print('服务端启动....')
    
        conn,addr = s.accept()
        path = settings.path                            #设定待存放文件路径
        while True:
            info = str(conn.recv(1024),'utf8')          #接受文件名和文件大小
            if not info:
                conn.close()
                conn,addr = s.accept()
                continue
            filename,filesize = info.split(',')         #分割出文件名和文件大小
            print('待传输的文件大小为:%s'%filesize)
            print('请稍后....')
            f = open(os.path.join(path,filename),'wb')  #创建文件
            recv_size =0                                #已接受数据的值,初始为0
            while recv_size != int(filesize):           #循环接受数据,直到数据接收完整
                data = conn.recv(1024)                  #每次接受1024个字节
                f.write(data)                           #每接受1024个就写入文件
                recv_size += len(data)                  #每接受一次增加同等值的已接受值
            f.close()
            print('传输完成')
        s.close()
    if __name__ == '__main__':
        recv()
    

     

    pic_client.py:

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    # author:yangva
    
    import socket,os
    import settings
    c = socket.socket()
    addr = ('127.0.0.1',8800)
    base_dir = settings.base_dir
    
    def send():
        print('客户端启动...')
        c.connect(addr)
    
        types,filename = input('>>>:').strip().split('/')   #分割出输入的传输方式、文件名
        if types != settings.transport_type:exit()          #传输方式
        path = os.path.join(base_dir,filename)              #拼凑文件名的绝对路径
        filesize = os.stat(path).st_size                    #文件名的空间大小
        info = '%s,%s'%(filename,filesize)
        c.sendall(bytes(info,'utf8'))                       #传输文件名、文件大小
    
        sent_size = 0                                       #设定初始值,用于标记已传输的大小
        f = open(path,'rb')
        while sent_size != filesize:                        #循环传入,直到传完整个文件
            data = f.read(1024)                             #每次读取1024个字节大小
            if not data:break
            c.sendall(data)                                 #传输读取的1024个字节
            sent_size += len(data)                          #每传输一次增加同等值的已接受值
        c.close()
    if __name__ == '__main__':
        send()
    

     

    好的,就这么些,我这里测试的是上传名为1.jpg的图片到test文件目录里

    先看下1.jpg:

     

    美女对吧。好的,开始测试:

    客户端:

    服务端:

     

    我们看下test目录:

     

    打开这个目录的1.jpg看看:

     

    这美女已经被我们传到test目录里了,验证的文件大小看看:

     

    和刚才的对比:

     

     

    好的,是的,那么这个项目就搞定了。很简单对不对

     

     项目二:用socketserver模块实现并发,多用户同时访问

     项目要求:使用socketserver模块操作实现多用户同时访问服务端

     

    是的,你没有看错,项目要求就这么一个,最根本的就是熟悉socketserver模块的使用方法就行。

    所以本项目的前提,先学习socketserver模块,不用多说,就一句话,socketserver是在socket基础之上开发的,类似于一个框架,里面的大部分东西是给我们写好的,稍微的学习socketserver的使用方法就行,其他和socket是完全没区别的。

     

    好的,不多说,直接上来。

     

    项目结构就两个con_server.py和con_client.py。

     

    con_server.py:

     

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    
    import socketserver
    
    class myserver(socketserver.BaseRequestHandler):
        def handle(self):                               #这里的方法名是固定的,不能是其他的
            print('服务端启动。。。')
            while True:
                conn = self.request                     #和conn,addr = socket.accept()等同
                print(self.client_address)
                while True:
                    client_data = conn.recv(1024)       #接受数据
                    print(str(client_data,'utf8'))      #转为字符串
                    req = input('>>>:')                 #输入数据
                    conn.sendall(bytes(req,'utf8'))     #发送数据
                conn.close()
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),myserver)
        server.serve_forever()                          #服务永远存在,不关闭
    

     

    con_client.py:

    和前面的完全一样,没做任何更改

    #!usr/bin/env python
    #-*- coding:utf-8 -*-
    
    # author:yangva
    
    import socket
    address = ('127.0.0.1',8888)
    c = socket.socket()
    c.connect(address)
    print('客户端启动。。。')
    while True:
        data = input('>>>:')
        c.send(bytes(data,'utf8'))
        if data == 'exit':break
        res_data = c.recv(1024)
        print(str(res_data,'utf8'))
    c.close()
    

     

    好的,运行测试:

    第一个客户端:

     第二个客户端:

    第三个客户端:

     

    服务端:

     

    查看结果:

    第一个客户端收到信息:

    第二个客户端收到信息:

    第三个客户端收到信息:

    那么就是都收发到了的,服务端回复的内容会按连接的先后顺序依次分发给客户端。那么并发就实现了。

    这个真么什么难度,具体就自己下去多研究了

    好的,项目结束,都是很简单的小项目

     

  • 相关阅读:
    vue 分页 pagination
    查看android 签名文件keystore的有效期限
    cordova + vue 项目实现极光推送功能
    vue window
    input
    vue install 组件
    cordova 的安桌动画
    深度图
    css3 Transition动画执行时有可能会出现闪烁的bug
    windows zip命令
  • 原文地址:https://www.cnblogs.com/Eeyhan/p/8443453.html
Copyright © 2011-2022 走看看