Python3.6:socket实现文件传输

作者: james_chang | 来源:发表于2018-02-13 15:55 被阅读22次

既然我们实现了简单的数据传输和简单的ssh客户端,那么我们能不能实现传输文件呢?

先理一理思路,实现简单ssh客户端时有个要点就是接收的数据有时候会大于我们给定的1024,需要循环接收,那么文件不也是一个道理?先发送文件大小,只要还没有收到这个大小的数据就说明没有收完,一直到收到的数据的大小和发送来的数据大小一样就行了为了防止出错,我们还可以加上md5验证,这样就不会出错了

服务器端:

# 1.读取客户端发来的文件名
# 2.查找文件是否存在
# 3.打开该文件
# 4.检测文件大小
# 5.发送大小给客户端
# 6.等待客户端确认
# 7.开始边读边发
# 8.发送md5校验

import socket
import os
import hashlib

server = socket.socket()
server.bind(('localhost', 8080))
server.listen()
while True:
    conn, addr = server.accept()
    print('等待指令:')
    while True:
        data = conn.recv(1024)
        if not data:
            print('客户端断开')
            break

        # 第一次接收的是命令,包括get和文件名,用filename接受文件名
        cmd, filename = data.decode().split()

        # 接收到的文件名判断是不是一个文件
        if os.path.isfile(filename):

            # 如果是,读模式打开这个文件
            f = open(filename, 'rb')

            # 生成md5对象
            m = hashlib.md5()

            # 将文件大小赋值给file_size
            file_size = os.stat(filename).st_size

            # 发送文件大小
            conn.send(str(file_size).encode())

            # 接收确认信息
            conn.recv(1024)

            # 开始发文件
            for line in f:

                # 发一行更新一下md5的值,因为不能直接md5文件,到最后读完就是一个文件的md5的值
                m.update(line)

                # 一行一行发送
                conn.send(line)

            # 打印挣个文件的md5
            print('file md5:', m.hexdigest())

            # 关闭文件
            f.close()

            # send md5
            conn.send(m.hexdigest().encode())
        print('send done')
    break
server.close()

客户端:

import socket
import hashlib
client = socket.socket()
client.connect(('localhost', 8080))

while True:

    # 获得命令和想要下载的文件   格式:get xxxx
    cmd = input('what do u want?:').strip()

    # 判断如果获得的字符串中有'get'开始执行一下步骤
    if cmd.startswith('get'):

        # 发送指令
        client.send(cmd.encode())

        # 接收文件大小
        response = client.recv(1024)
        print('file size:', response.decode())

        # 发送确认信息
        client.send(b'111')

        # 转整形,方便下面大小判断
        file_size = int(response.decode())

        # 赋值方便最后打印大小
        new_file_size = file_size

        # 将命令分割获得文件名
        filename = cmd.split()[1]

        # 写模式创建文件
        f = open(filename, 'wb')

        # 生成md5对象
        m = hashlib.md5()

        # 进入循环判断收文件
        while new_file_size > 0:
            data = client.recv(1024)
            
            # 收多少减多少
            new_file_size -= len(data)
            
            # 同步服务器端,收一次更新一次md5
            m.update(data)
            
            # 写入数据
            f.write(data)
        else:
            
            # 得到下载完的文件的md5
            new_file_md5 = m.hexdigest()
            
            # 打印下载文件大小
            print('file recv done', file_size)
            f.close()
            
        # 接收服务器端的文件的md5
        server_file_md5 = client.recv(1024)
        
        # 打印两端的md5值,看是否相同
        print('server file md5:', server_file_md5)
        print('recv file md5:', new_file_md5)

    else:
        continue

其实只要理顺了逻辑,就能很轻易的写出来,当然要注意一些容易犯错的点

在客户端跟服务器端的交互中,服务器端的发送接收跟客户端的发送接收是一一对应的,这是重点中的重点,只要记住这个,就可以实现自己的逻辑

还有就是粘包的问题,尽量避免两条send语句紧挨,如果出现紧挨的情况就要想办法解决粘包的问题

文件不能直接md5,需要读取一行数据更新一次md5的值
还有就是数据的编码解码问题

相关文章

  • Python3.6:socket实现文件传输

    既然我们实现了简单的数据传输和简单的ssh客户端,那么我们能不能实现传输文件呢? 先理一理思路,实现简单ssh客户...

  • 知识点

    网络编程 我项目中Socket是怎么实现IM通讯的;Socket通讯,怎么实现图片,大文件传输;http报文结构;...

  • Socket实现文件传输

    使用了socket库来实现网络文件的传输,封装了下,希望您会喜欢,有任何问题也可以联系我 客户端 服务端: Usage:

  • Go基础编程---网络(socket)编程

    socket编程 服务器编码---多协程和服务器通信 文件传输程序 go实现--聊天室---代码

  • 16.socket文件传输功能的实现

    这节我们来完成 socket 文件传输程序,这是一个非常实用的例子。要实现的功能为:client 从 server...

  • Socket文件传输

    服务器端(字节流): import java.io.BufferedReader;import java.io.B...

  • Python3.6:socket实现简单传输数据

    客户端: 服务器端: 先运行服务器端,后运行客户端: 需要注意的几个点: 编码问题,因为只支持bytes类型数据,...

  • 网络应用层协议

    FTP:文件传输协议(File Transfer Protocol,FTP):用于实现交互式文件传输功能 DNS:...

  • Python Socket编程:利用SMTP发送MIME协议邮件

    2017年12月31日更新 代码更新为最新的OOP代码,测试环境Python3.6,成功发送邮件。 Socket编...

  • Python3.6:socket实现简单ssh客户端

    如果你看过了上篇文章ssh实现简单的数据传输,那么实现简单的ssh客户端也不是什么问题,无非就是在服务器端利用os...

网友评论

    本文标题:Python3.6:socket实现文件传输

    本文链接:https://www.haomeiwen.com/subject/iybjtftx.html