一、文件传送步骤

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

  服务端:

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

  客户端:

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

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

  服务端:

# -*- coding: UTF-8 -*-
import os
import socket # TCP/IP协议, tcp ,如果不填写就是默认这个
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 9999)) server.listen() while True: # 可以接受多个客户端 conn, addr = server.accept()
print('new conn', addr)
while True: cmd_res = conn.recv(1024)
if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉
print('client has lost...')
break
else:
# 获取命令和文件名
cmd, filename = cmd_res.decode().split()
print(cmd, filename)
if os.path.isfile(filename): # 判断文件是否存在
# 文件大小
file_size = os.stat(filename).st_size
# 发送文件大小
conn.send(str(file_size).encode(encoding='utf-8'))
# 等待客户端确认
conn.recv(1024)
# 打开文件
f = open(filename, 'rb')
for line in f:
conn.send(line)
print('sending')
f.close()

  客户端:

# -*- coding: UTF-8 -*-
import socket client = socket.socket() client.connect(('localhost', 9999)) while True:
cmd = input('>>:').strip()
# 判断是否发送空数据,如果是就重新发送
if len(cmd) == 0:
continue
else:
client.send(cmd.encode('utf-8'))
# 获取服务端发送的文件大小
size = client.recv(1024)
total_file_size = int(size.decode()) # 返回确认
client.send(b'file size received')
filename = cmd.split()[1]
print(filename)
received_size = 0
# 写入文件
f = open(filename + '.new', 'w', encoding='utf-8')
while received_size < total_file_size:
r_data = client.recv(1024)
received_size += len(r_data)
f.write(r_data.decode() + '\n')
else:
print('file sizes', total_file_size, received_size)
print('receive finished')
f.close()

 有些问题 替换一些内容

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

   

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

三、md5验证文件

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

  服务端:

# -*- coding: UTF-8 -*-
import os
import socket
import hashlib # TCP/IP协议, tcp ,如果不填写就是默认这个
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 9999)) server.listen() while True: # 可以接受多个客户端 conn, addr = server.accept()
print('new conn', addr)
while True: cmd_res = conn.recv(1024)
if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉
print('client has lost...')
break
else:
# md5
m = hashlib.md5()
# 获取命令和文件名
cmd, filename = cmd_res.decode().split()
print(cmd, filename)
if os.path.isfile(filename): # 判断文件是否存在
# 文件大小
file_size = os.stat(filename).st_size
print(file_size)
# 发送文件大小
conn.send(str(file_size).encode(encoding='utf-8'))
# 等待客户端确认
conn.recv(1024)
# 打开文件
f = open(filename, 'rb')
for line in f:
m.update(line)
# m.update('abc') m.update('123')
# 其实和m.update('abc123') 结果一下
conn.send(line) f.close()
print('send done')
# 发送md5信息
conn.send(m.hexdigest().encode('utf-8'))

  客户端:

# -*- coding: UTF-8 -*-
import socket
import hashlib client = socket.socket() client.connect(('localhost', 9999)) while True:
cmd = input('>>:').strip()
# 判断是否发送空数据,如果是就重新发送
if len(cmd) == 0:
continue
else:
client.send(cmd.encode('utf-8'))
# 获取服务端发送的文件大小
f_size = client.recv(1024)
total_file_size = int(f_size.decode()) # 返回确认
client.send(b'file size received')
filename = cmd.split()[1]
print(filename)
received_size = 0
# md5
m = hashlib.md5() # 写入文件
f = open(filename + '.new', 'wb') # 新生成的文件也正常显示
while received_size < total_file_size:
if total_file_size - received_size > 1024: # 以此来控制只收文件的内容,不会粘包md5的内容
size = 1024
else:
size = total_file_size - received_size
r_data = client.recv(size)
received_size += len(r_data)
m.update(r_data)
f.write(r_data)
# print(r_data.decode())
# print('file sizes', total_file_size, received_size)
else:
print('file sizes', total_file_size, received_size)
server_md5 = client.recv(1024).decode()
client_md5 = m.hexdigest()
print(server_md5)
print(client_md5)
print('receive finished')
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. Tree - Gradient Boosting Machine with sklearn source code

    This is the second post in Boosting algorithm. In the previous post, we go through the earliest Boos ...

  2. 【Python进阶】用 Python 统计字数

    问题描述: 用 Python 实现函数 count_words(),该函数输入字符串 s 和数字 n,返回 s 中 n 个出现频率最高的单词.返回值是一个元组列表,包含出现次数最高的 n 个单词及其次 ...

  3. eclipse技巧-快捷键

    ctrl + 1,快速修复 ctrl + d, 快捷删除行 shift + Enter,快速移动光标到下一行 ctrl + F11,运行代码 alt + ↑/↓,快速移动行 ctrl + alt + ...

  4. 王者荣耀交流协会第三次Scrum立会

    会议时间:2017年10月22号   18:00-18:32,时长32分钟. 会议地点:中快餐厅二楼第二排倒数第二个桌子. 立会内容: 1.每位同学汇报了今日工作. 2.通过讨论我们决定用存excel ...

  5. <<世界是数字的>>读书笔记

    <世界是数字的>这本书是大学职业规划老师介绍个我读的,从着本中我学到了很多. 第一章,计算机里有什么.这个问题可以从两方面来看:逻辑上或者说功能上的组成,即每一部分是什么.做什么.怎样做. ...

  6. 使用Python 、 go 语言测试rabbitmq的工作机制

    1:在haproxy 和 rabbitmq上安装Python.python2-pip,默认是Python2 yum install -y python python2-pip   2:在haproxy ...

  7. PAT 甲级 1050 String Subtraction

    https://pintia.cn/problem-sets/994805342720868352/problems/994805429018673152 Given two strings S~1~ ...

  8. js动态显示指定的时间

    <p id="timeShow">17:0:50</p> <script> setInterval("time()", 10 ...

  9. 微信小程序组件 360

    data: { nums: 1, start: '', // change:'' // 上一部记忆数据 mid: '' }, mytouchmove: function (e) { var start ...

  10. 【前端学习笔记04】JavaScript数据通信Ajax方法封装

    //Ajax 方法封装 //设置数据格式 function setData(data){ if(!data){ return ''; } else{ var arr = []; for(k in da ...