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)休息一下就解决 ...
随机推荐
- 作业要求20181016-3 Alpha阶段第1周/共2周 Scrum立会报告+燃尽图 01
此次作业要求参见https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 Scrum master:范洪达 一.小组介绍 组长:王一可 组员 ...
- 第四周 实验一 Java开发环境的熟悉 报告
Java开发环境的熟悉 实验内容 1.IDEA的安装过程 2.使用IDEA代替虚拟机运行.编译.调试Java程序 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)&g ...
- mysql---时间类型详解
mysql 日期类型 mysql 日期类型 · DATE (适用于"出生日期"等只需要年月日数据的日期字段) 日期.支持的范围为'1000-01-01'到'9999-12- ...
- caffe环境搭建笔记
首先安装以下库或软件 sudo apt-get install gitsudo apt-get install libprotobuf-dev libleveldb-dev l ...
- 运维学习笔记(三)之T01-03TCP/IP
TCP/IP协议 简介 通信协议 信息从源传递到目的地的过程中,网络上各设备需要通信,描述网络通信“语言”的规范就是协议. 数据通信协议 决定数据的格式和传输的一组规则. TCP/IP协议简介 一组通 ...
- 0302借软件工程触IT
没有不想学好的学生,也没有选择计算机软件专业后不想过能进军IT的行业的.就对于自己情况来说,大学选择计算机商业软件专业学习也有一年多时间了,未接触专业知识前IT是一个高大上的向往,在初学C语 ...
- 爬虫学习之-操作mysql
在操作数据库的时候,python2中一般使用mysqldb,但在python3中已经不在支持mysqldb了,我们可以用pymysql和mysql.connector.本文的所有操作都是在python ...
- 爬虫学习之-sqlite3
SQLlte数据类型 SQLite能保存什么样的数据类型 ?? 可以保存空值.整数.浮点数.字符串和blob. 什么是blob ?? 是二进制大对象.例如图片.音乐.zip文件. 什么是游标 ?? 游 ...
- 【比赛】HNOI2018 毒瘤
虚树+dp 直接看zlttttt的强大题解 zlttttt的题解看这里 #include<bits/stdc++.h> #define ui unsigned int #define ll ...
- 【BZOJ3894】文理分科(最小割)
[BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...