一、文件传送步骤

  我们要利用socket来实现下载一个文件,该如何操作呢?

  服务端:

  1. 读取文件名
  2. 判断文件是否存在
  3. 检测文件大小(用于和客户端对比判断文件是否传送完毕)
  4. 发送文件大小给客户端
  5. 等待客户端确认(防止粘包)
  6. 打开文件
  7. 边读边发送数据
  8. md5验证

  客户端:

  • 发送命令
  • 接收文件大小
  • 返回确认
  • 获取文件名
  • 对比文件大小
  • 写入文件

二、功能实现(ftp下载功能)

  服务端:

  1. # -*- coding: UTF-8 -*-
  2. import os
  3. import socket
  4.  
  5. # TCP/IP协议, tcp ,如果不填写就是默认这个
  6. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  7.  
  8. server.bind(('localhost', 9999))
  9.  
  10. server.listen()
  11.  
  12. while True: # 可以接受多个客户端
  13.  
  14. conn, addr = server.accept()
  15. print('new conn', addr)
  16. while True:
  17.  
  18. cmd_res = conn.recv(1024)
  19. if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉
  20. print('client has lost...')
  21. break
  22. else:
  23. # 获取命令和文件名
  24. cmd, filename = cmd_res.decode().split()
  25. print(cmd, filename)
  26. if os.path.isfile(filename): # 判断文件是否存在
  27. # 文件大小
  28. file_size = os.stat(filename).st_size
  29. # 发送文件大小
  30. conn.send(str(file_size).encode(encoding='utf-8'))
  31. # 等待客户端确认
  32. conn.recv(1024)
  33. # 打开文件
  34. f = open(filename, 'rb')
  35. for line in f:
  36. conn.send(line)
  37. print('sending')
  38. f.close()

  客户端:

  1. # -*- coding: UTF-8 -*-
  2. import socket
  3.  
  4. client = socket.socket()
  5.  
  6. client.connect(('localhost', 9999))
  7.  
  8. while True:
  9. cmd = input('>>:').strip()
  10. # 判断是否发送空数据,如果是就重新发送
  11. if len(cmd) == 0:
  12. continue
  13. else:
  14. client.send(cmd.encode('utf-8'))
  15. # 获取服务端发送的文件大小
  16. size = client.recv(1024)
  17. total_file_size = int(size.decode())
  18.  
  19. # 返回确认
  20. client.send(b'file size received')
  21. filename = cmd.split()[1]
  22. print(filename)
  23. received_size = 0
  24. # 写入文件
  25. f = open(filename + '.new', 'w', encoding='utf-8')
  26. while received_size < total_file_size:
  27. r_data = client.recv(1024)
  28. received_size += len(r_data)
  29. f.write(r_data.decode() + '\n')
  30. else:
  31. print('file sizes', total_file_size, received_size)
  32. print('receive finished')
  33. f.close()

 有些问题 替换一些内容

  1. f = open(filename + '.new', 'wb')
  1. f.write(r_data)

   

  这个程序有缺陷,首先目前只能读取本文件夹下的文件,新生成的文件没有中文乱码问题,ok...

三、md5验证文件

  加个md5来验证文件是否一致

  服务端:

  1. # -*- coding: UTF-8 -*-
  2. import os
  3. import socket
  4. import hashlib
  5.  
  6. # TCP/IP协议, tcp ,如果不填写就是默认这个
  7. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  8.  
  9. server.bind(('localhost', 9999))
  10.  
  11. server.listen()
  12.  
  13. while True: # 可以接受多个客户端
  14.  
  15. conn, addr = server.accept()
  16. print('new conn', addr)
  17. while True:
  18.  
  19. cmd_res = conn.recv(1024)
  20. if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉
  21. print('client has lost...')
  22. break
  23. else:
  24. # md5
  25. m = hashlib.md5()
  26. # 获取命令和文件名
  27. cmd, filename = cmd_res.decode().split()
  28. print(cmd, filename)
  29. if os.path.isfile(filename): # 判断文件是否存在
  30. # 文件大小
  31. file_size = os.stat(filename).st_size
  32. print(file_size)
  33. # 发送文件大小
  34. conn.send(str(file_size).encode(encoding='utf-8'))
  35. # 等待客户端确认
  36. conn.recv(1024)
  37. # 打开文件
  38. f = open(filename, 'rb')
  39. for line in f:
  40. m.update(line)
  41. # m.update('abc') m.update('123')
  42. # 其实和m.update('abc123') 结果一下
  43. conn.send(line)
  44.  
  45. f.close()
  46. print('send done')
  47. # 发送md5信息
  48. conn.send(m.hexdigest().encode('utf-8'))

  客户端:

  1. # -*- coding: UTF-8 -*-
  2. import socket
  3. import hashlib
  4.  
  5. client = socket.socket()
  6.  
  7. client.connect(('localhost', 9999))
  8.  
  9. while True:
  10. cmd = input('>>:').strip()
  11. # 判断是否发送空数据,如果是就重新发送
  12. if len(cmd) == 0:
  13. continue
  14. else:
  15. client.send(cmd.encode('utf-8'))
  16. # 获取服务端发送的文件大小
  17. f_size = client.recv(1024)
  18. total_file_size = int(f_size.decode())
  19.  
  20. # 返回确认
  21. client.send(b'file size received')
  22. filename = cmd.split()[1]
  23. print(filename)
  24. received_size = 0
  25. # md5
  26. m = hashlib.md5()
  27.  
  28. # 写入文件
  29. f = open(filename + '.new', 'wb') # 新生成的文件也正常显示
  30. while received_size < total_file_size:
  31. if total_file_size - received_size > 1024: # 以此来控制只收文件的内容,不会粘包md5的内容
  32. size = 1024
  33. else:
  34. size = total_file_size - received_size
  35. r_data = client.recv(size)
  36. received_size += len(r_data)
  37. m.update(r_data)
  38. f.write(r_data)
  39. # print(r_data.decode())
  40. # print('file sizes', total_file_size, received_size)
  41. else:
  42. print('file sizes', total_file_size, received_size)
  43. server_md5 = client.recv(1024).decode()
  44. client_md5 = m.hexdigest()
  45. print(server_md5)
  46. print(client_md5)
  47. print('receive finished')
  48. f.close()

  结果:

  

  结果看上去没有问题了,新文件也能生成,并且有内容

socket传送文件的更多相关文章

  1. Socket 传送文件

    1.传送文本文件 1.1服务端 package com; import java.io.BufferedWriter; import java.io.DataInputStream; import j ...

  2. socket传送文件格式的问题

    在python3中socket传送文件只能传送‘bytes'类型,如下例子: import socket client = socket.socket()client.connect(("l ...

  3. C语言sendto()函数-经socket传送数据以及recvfrom函数《转》

    相关函数:send, sendmsg, recv, recvfrom, socket 头文件:#include <sys/types.h>   #include <sys/socke ...

  4. python socket 传输文件

    推荐资料 https://www.cnblogs.com/xiaokang01/p/9865724.html socket传输文件 思路: # 先将报头转换成字符串(json.dumps), 再将字符 ...

  5. SZ,RZ传送文件

    linux 和window之间通过xshell的命令 SZ,RZ传送文件:

  6. socket头文件

    一. 三种类型的套接字:1.流式套接字(SOCKET_STREAM)    提供面向连接的可靠的数据传输服务.数据被看作是字节流,无长度限制.例如FTP协议就采用这种.2.数据报式套接字(SOCKET ...

  7. python使用简单http协议来传送文件

    python使用简单http协议来传送文件!在ubuntu环境下,局域网内可以使用nc来传送文件,也可以使用基于Http协议的方式来下载文件我们可以使用python -m SimpleHTTPServ ...

  8. Linux SSH 远程操作与传送文件

    操作系统:centos 6.5 x64 一.远程连接:在进行linux 的 ssh远程操作前,一定要确认linux 是否安装了 openssh-clients,为了方便起见,一般用yum安装即可:# ...

  9. Java使用Socket传输文件遇到的问题(转)

    1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...

随机推荐

  1. Tensorflow - Implement for a Softmax Regression Model on MNIST.

    Coding according to TensorFlow 官方文档中文版 import tensorflow as tf from tensorflow.examples.tutorials.mn ...

  2. python基础知识-7-内存、深浅、文件操作

    python其他知识目录 1.一些对内存深入理解的案例 以下列举列表,列表/字典/集合这些可变类型都是一样的原理 变量是个地址,指向存储数据的内存空间的地址,它的实质就相当于c语言里的指针.变量和数据 ...

  3. Linux sync命令的作用分析

    Sync命令   在用reboot命令启动unix系统后,系统提示出错信息,部分应用程序不能正常工作.经仔细检查系统文件,并和初始的正确备份进行比较,发现某些文件确实被破坏了,翻来覆去找不到文件遭破坏 ...

  4. python3【基础】-文件操作

    1. python对文件操作流程: 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件操作 关闭文件 现有如下文件: 昨夜寒蛩不住鸣. 惊回千里梦,已三更. 起来独自绕阶行. 人悄悄,帘外月胧明. ...

  5. 《构建之法》6-7章读后感、问题及对Scrum的理解

    第6章读后感: 看完第六章后了解什么是敏捷流程.“敏捷流程”在软件工程的语境中是一系列价值观和方法论的集合.我觉得敏捷是比较人性化而且让人比较轻松的的一种团队做项目的方法吧,它会比较注重交流,而不是硬 ...

  6. c# 画image

    这是一个例子,从数据库中读取然后赋伪彩,生成bitmap,给到imagebox控件(其image属性为平铺). https://pan.baidu.com/s/1hf_fGFHjGoDK_gywuhg ...

  7. 团队Alpha冲刺(二)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  8. Windows Forms编程实战学习:第一章 初识Windows Forms

    初识Windows Forms 1,用C#编程 using System.Windows.Forms;   [assembly: System.Reflection.AssemblyVersion(& ...

  9. Java设计模式 - 单例模式 (懒汉方式和饿汉方式)

    概念: Java中单例模式是一种常见的设计模式,单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的写法有好几种,这 ...

  10. BER-TLV数据结构【转】

    转自:https://www.cnblogs.com/SCPlatform/p/5076935.html 为了便于后文的引用说明,先列出一段TLV结构的数据: [6F] 4D │ ├─[84] 07 ...