Python使用socket传输文件
在局域网下,不同主机之间可以使用socket进行通信。
首先,要获取服务端的ip地址:
1. linux系统:输入命令ifconfig
2. windows系统:win+R输入cmd进入命令行,输入ipconfig
在Windows与虚拟机ubuntu下进行了文件传输尝试:
(两种写法类似,都能成功进行文件传输,代码中的IP均为服务端的IP地址)
写法一:
服务端server.py
# 服务端
# -*- coding=utf-8 -*-
import socket
import threading
import sys
import os
import structdef deal_data(conn, addr):print('Accept new connection from {0}'.format(addr))while True:fileinfo_size = struct.calcsize('128sq') # linux 和 windows 互传 128sl 改为 128sq 机器位数不一样,一个32位一个64位buf = conn.recv(fileinfo_size)print('收到的字节流:', buf, type(buf))if buf:print(buf, type(buf))filename, filesize = struct.unpack('128sq', buf)fn = filename.strip(str.encode('\00'))new_filename = os.path.join(str.encode('./'), str.encode('new_') + fn)print('file new name is {0}, filesize if {1}'.format(new_filename, filesize))recvd_size = 0 # 定义已接收文件的大小with open(new_filename, 'wb') as fp:print("start receiving...")while not recvd_size == filesize:if filesize - recvd_size > 1024:data = conn.recv(1024)recvd_size += len(data)else:data = conn.recv(filesize - recvd_size)recvd_size = filesizefp.write(data)print("end receive...")conn.close()breakdef socket_service():try:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 修改ip,此处ip必须为服务器端的ip ,linux做服务器输入ifconfig得到ips.bind(('192.168.159.128', 5555))s.listen(10)except socket.error as msg:print(msg)sys.exit(1)print("Waiting...")while True:conn, addr = s.accept()t = threading.Thread(target=deal_data, args=(conn, addr))t.start()if __name__ == '__main__':socket_service()
客户端client.py
# -*- coding=utf-8 -*-import socket
import os
import sys
import structdef socket_client():try:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 修改ips.connect(('192.168.159.128', 5555))# 此处ip必须为服务器端的ipexcept socket.error as msg:print(msg)sys.exit(1)while True:filepath = '10.jpg' # 传输文件的路径if os.path.isfile(filepath):# 定义定义文件信息。128s表示文件名为128bytes长,l表示一个int或log文件类型,在此为文件大小fileinfo_size = struct.calcsize('128sq')# 定义文件头信息,包含文件名和文件大小fhead = struct.pack('128sq', bytes(os.path.basename(filepath).encode('utf-8')), os.stat(filepath).st_size)s.send(fhead)print('client filepath: {0}'.format(filepath))with open(filepath, 'rb') as fp:while True:data = fp.read(1024)if not data:print('{0} file send over...'.format(filepath))breaks.send(data)s.close()breakif __name__ == '__main__':socket_client()
运行结果:
1.先在linux端运行server.py,再在windows运行client.py,IP地址为linux的ip
linux: 传过来的文件保存在当前文件夹下,并在文件名前加前缀new_
windows:
2. windows作服务端,linux作客户端,ip地址均改为windows的ip
windows:
linux:
写法二:注意两个IP地址都为服务器端的IP!
服务端service.py
import socket
import os
import sys
import structdef socket_service_image():try:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)s.bind(('192.168.159.128', 6000))s.listen(10)except socket.error as msg:print(msg)sys.exit(1)print("Wait for Connection.....................")while True:sock, address = s.accept() # addr是一个元组(ip,port)deal_image(sock, address)def deal_image(sock, address):print("Accept connection from {0}".format(address)) # 查看发送端的ip和端口while True:fileinfo_size = struct.calcsize('128sq') # 返回格式字符串fmt描述的结构的字节大小print('fileinfo_size is', fileinfo_size)buf = sock.recv(fileinfo_size) # 接收图片名print('buf is ', buf)if buf: # 如果接收到了数据就开始接下来的操作filename, filesize = struct.unpack('128sq', buf) # 按照客户端打包的格式进行解包,得到图片的名字和图片大小print('filename :', filename.decode(), 'filesize :', filesize)# fn = filename.decode().strip('\x00') # 其实,这里的filename已经是解码完毕去掉字节符号的样子了,我感觉这一步是多此一举fn = filename.strip(str.encode('\00'))print('fn is ', fn)new_filename = os.path.join(str.encode('./'), str.encode('new_') + fn)print(new_filename)# 在服务器端新建图片名(可以不用新建的,直接用原来的也行,只要客户端和服务器不是同一个系统或接收到的图片和原图片不在一个文件夹下)recvd_size = 0fp = open(new_filename, 'wb') # 二进制打开文件while not recvd_size == filesize: # 如果收到的直接总数不等于这个文件的直接总数,那么就继续接受数据if filesize - recvd_size > 1024: # 这个最后一次如果数据比data = sock.recv(1024) # 每次从客户端接受1024个字节recvd_size += len(data) # 每次都记录好收到的字节数,然后叠加上去else: # 这个最后一次数据如果比1024少的话那么这一次读完就OK了,而且这次结束后循环也就结束了data = sock.recv(1024)recvd_size = filesizeprint('data is', data) # 输出每一次收到的数据fp.write(data) # 写入图片数据,因为每次都是读取到1024个字节,所以每一次读取都需要把得到的字节进行拼凑fp.close()sock.close()breakif __name__ == '__main__':socket_service_image()
客户端client.py
import socket
import os
import sys
import structdef sock_client_image():while True:try:s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('192.168.159.128', 6000))except socket.error as msg:print(msg)print(sys.exit(1))file_path = 'a.jpg' # 输入当前目录下的图片名# pack按照图片格式、图片名字、图片大小fhead = struct.pack(b'128sq', # 图片打包的格式为128sqbytes(os.path.basename(file_path), encoding='utf-8'), # 返回图片文件名,编码字节化os.stat(file_path).st_size) # 返回读取文件的相关属性,然后得到其中st_size的数据(记录文件大小)s.send(fhead)fp = open(file_path, 'rb') # 打开要传输的图片while True:data = fp.read(1024) # 读入图片数据,data是图片的数据字节流(由于图片字节很多,这里一次只读取1024个字节)if not data: # 如果读到字节的数据没有了print('{0} send over...'.format(file_path))breaks.send(data) # 以二进制格式发送图片数据(每次发1024个字节)s.close()break # 如果需要一直发送图片则需要在这里进行修改if __name__ == '__main__':sock_client_image()
Python使用socket传输文件相关推荐
- C#实战之CAD二次开发006:与python进行Socket传输文件
前言 前面介绍了与CAD相关的一些功能,本期介绍一下C#和python如何通过socket通信来进行文件的传输,建议不了解Socket的同学先去了解一下socket的通讯原理,这样看起来不会云里雾里的 ...
- Linux下使用socket传输文件的C语言简单实现
转载:http://blog.csdn.net/ljd_1986413/article/details/7940938 服务器程序和客户端程序应当分别运行在两台计算机上. 在运行服务器端的计算机终端执 ...
- 浅谈socket传输文件速率优化
socket传输文件速率优化 前言 最近有个需求,就是在需要提升换机助手的传输文件的传输速度.先来看看什么是换机助手. 一般厂家的换机助手都长这个样子,就是将旧手机的一些数据拷贝到新手机上去.数据一般 ...
- OIO下的socket传输文件
OIO下的io操作 正常的情况下,我们的服务端连接是同步进行的,所以每次收到客户端的连接后都需要等待当前客户端处理完毕之后才会继续处理下一个请求.这个OIO下的网络编程的缺点,但是我们可以使用单独的线 ...
- java通过socket传输文件
客户端代码 package 基于socket的文件传输;import java.io.DataInputStream; import java.io.DataOutputStream; import ...
- python内网传输文件,无需下载其他软件
通常我们在进行两台电脑间文件传输时,一般都通过QQ或者微信,亦或者下载其他软件来完成,本文将给大家推荐一个更简单的方法来实现两台电脑间的文件传输,前提是两台电脑必须在同一局域网内. 我们将两台电脑分为 ...
- java文件传输连接方式_Java 学习笔记 网络编程 使用Socket传输文件 CS模式
Socket的简单认识 Socket是一种面向连接的通信协议,Socket应用程序是一种C/S(Client端/Server端)结构的应用程序 Socket是两台机器间通信的端点. Socket是连接 ...
- Python 通过adb传输文件到手机
准备 手机开启开发者模式 USB或wifi连接到电脑调试 电脑安装了adb,并配置了环境变量 Python代码 import os import sys import datetime from sh ...
- python http协议传输文件的接口形式:POST {url:port}
http协议是常用的网络传输协议,只要给出一个网络接口即可 可以在浏览器窗口那里测试网上是否通 url:port 在python里,可以使用requests包来实现 继续在代码里分享 impor ...
最新文章
- Golang websocket
- echarts雷达图线的样式_echarts 雷达图的个性化设置
- Windows Mysql添加用户
- VTK:图像正弦曲线用法实战
- IBASE save
- dbgrid 获取前台页面参数
- SSL/TLS捕包分析
- 华为P50系列已适配鸿蒙OS 2.0 Beta2:有望4月亮相
- 检测磁盘是否有问题的方法
- Ubuntu下为Hadoop安装配置Hbase教程
- 史上最全的微信小程序代码大全分享
- nano命令,vi ed pico sed joe emacs jed ex
- 2.4GHz频段天线的选择
- python初探偏微分方程数值解
- linux 2.6.28.7 各驱动代码位置(待验证,已验证为蓝色标识)
- python(matplotlib)绘制直方图及阶梯图
- XJTU第八周大计基编程作业
- Caused by: java.lang.NoSuchMethodError:No virtual method isSuccess()Z in class Lretrofit2/Response;
- Grin交易原理详解
- python双等号是什么意思_python中等号是什么意思?