socket传送文件
一、文件传送步骤
我们要利用socket来实现下载一个文件,该如何操作呢?
服务端:
- 读取文件名
- 判断文件是否存在
- 检测文件大小(用于和客户端对比判断文件是否传送完毕)
- 发送文件大小给客户端
- 等待客户端确认(防止粘包)
- 打开文件
- 边读边发送数据
- 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传送文件的更多相关文章
- Socket 传送文件
1.传送文本文件 1.1服务端 package com; import java.io.BufferedWriter; import java.io.DataInputStream; import j ...
- socket传送文件格式的问题
在python3中socket传送文件只能传送‘bytes'类型,如下例子: import socket client = socket.socket()client.connect(("l ...
- C语言sendto()函数-经socket传送数据以及recvfrom函数《转》
相关函数:send, sendmsg, recv, recvfrom, socket 头文件:#include <sys/types.h> #include <sys/socke ...
- python socket 传输文件
推荐资料 https://www.cnblogs.com/xiaokang01/p/9865724.html socket传输文件 思路: # 先将报头转换成字符串(json.dumps), 再将字符 ...
- SZ,RZ传送文件
linux 和window之间通过xshell的命令 SZ,RZ传送文件:
- socket头文件
一. 三种类型的套接字:1.流式套接字(SOCKET_STREAM) 提供面向连接的可靠的数据传输服务.数据被看作是字节流,无长度限制.例如FTP协议就采用这种.2.数据报式套接字(SOCKET ...
- python使用简单http协议来传送文件
python使用简单http协议来传送文件!在ubuntu环境下,局域网内可以使用nc来传送文件,也可以使用基于Http协议的方式来下载文件我们可以使用python -m SimpleHTTPServ ...
- Linux SSH 远程操作与传送文件
操作系统:centos 6.5 x64 一.远程连接:在进行linux 的 ssh远程操作前,一定要确认linux 是否安装了 openssh-clients,为了方便起见,一般用yum安装即可:# ...
- Java使用Socket传输文件遇到的问题(转)
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
随机推荐
- Hyperledger Fabric中的Identity
Hyperledger Fabric中的Identity 什么是Identity 区块链网络中存在如下的角色:peers, orderers, client application, administ ...
- Alpha阶段中间产物——GUI Prototype、WBS及PSP
作业地址:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1224 内容: GUI Prototype 我的书架 我的书架→添加图书 ...
- 基于spec探路者团队贪吃蛇作品的评论
1 运动功能 由以上两图贪吃蛇的位置不同可知,运动功能实现.并且我能够通过使用键盘上的上下左右方位键控制蛇的移动方向,蛇在控制的方向上进行直线前进. 2 吃食物功能 以上两图可知吃食物功能实现.当界面 ...
- CS小分队第二阶段冲刺站立会议(5月29日)
昨日成果:昨天在为主界面设计自主添加应用快捷方式功能,连续遇到困难. 遇到的困难:1.string字符串数组无法在单击事件中使用,提示string无法在eventargs中检索,尝试了各种方式都不行 ...
- lintocde-247-线段树的查询 II
247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...
- 奇异值分解(SVD)原理详解及推导(转载)
转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/43053513 在网上看到有很多文章介绍SVD的,讲的也都不错,但是感觉还是有 ...
- perf的统计模式: 突破口: x86_perf_event_update
之前一直以为perf的统计模式也是通过中断出发来的,于是会在中断处理函数中做处理,但是如果perf是统计模式,那么perf的寄存器就不会是溢出的模式了,这个时候,就没有pmu的中断发生,所以很奇怪呢, ...
- linux安装py3.6
随手记录: https://www.python.org/ftp/python/3.6.8/Python-3.6.8rc1.tgz 所有linux版本: https://www.python.org/ ...
- 【移动端debug-2】Flexbox在移动端的兼容实践
最近在项目中用到了flexbox,总结一下使用心得. 一.什么是flexbox,干嘛使的? 曾几何时,我们特别希望能像word一样,在排版时有个分散对齐选项(平均分配子元素宽度)这样我就可以任意在父元 ...
- 第85天:HTML5语义化标签
一.语义标签 语义标签对于我们并不陌生,如<p>表示一个段落.<ul>表示一个无序列表<h1> ~ <h6>表示一系列标题等,在此基础上HTML5增加了 ...