python实现同一局域网下传输图片


Posted in Python onMarch 20, 2020

简述

Python可以通过网络套接字来进行传输图片
这点还是比较有意思的。

下面用TCP来进行实现,适用于Python3

代码功能简述

下面代码

  • 实现了在一个电脑上发送图片(Sender)
  • 实现了在另外一个电脑(也可以是同一个电脑上的不同端口)接受图片(Reciever)
  • 只发一次,然后只收一次
  • 新图片会在旧图片上多一个 “new_”前缀
  • 必须要先开接受者代码才行,之后再启动发送者代码(不然发送者代码会直接被拒绝)
  • 下面是固定了在一个电脑上(看ip地址,下面写的是127.0.0.1,如果是其他电脑就写其他电脑上的ip地址)
  • 另外本程序只能在同一个局域网下使用(就算是广域网上,那就必须要使用广域网的ip地址)

代码

【后附解析】

Sender.py (发送者)

import socket
import os
import sys
import struct


def sock_client():
  try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 6666))
  except socket.error as msg:
    print(msg)
    print(sys.exit(1))

  while True:
    filepath = input('input the file: ')
    # filepath = 'test.png'
    fhead = struct.pack(b'128sl', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)
    s.send(fhead)
    print('client filepath: {0}'.format(filepath))

    fp = open(filepath, 'rb')
    while 1:
      data = fp.read(1024)
      if not data:
        print('{0} file send over...'.format(filepath))
        break
      s.send(data)
    s.close()
    break


if __name__ == '__main__':
  sock_client()

Reciever.py (接受者)

import socket
import os
import sys
import struct


def socket_service():
  try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('127.0.0.1', 6666))
    s.listen(10)
  except socket.error as msg:
    print(msg)
    sys.exit(1)

  print("Wait")

  while True:
    sock, addr = s.accept()
    deal_data(sock, addr)
    break
  s.close()


def deal_data(sock, addr):
  print("Accept connection from {0}".format(addr))

  while True:
    fileinfo_size = struct.calcsize('128sl')
    buf = sock.recv(fileinfo_size)
    if buf:
      filename, filesize = struct.unpack('128sl', buf)
      fn = filename.decode().strip('\x00')
      new_filename = os.path.join('./', 'new_' + fn)

      recvd_size = 0
      fp = open(new_filename, 'wb')

      while not recvd_size == filesize:
        if filesize - recvd_size > 1024:
          data = sock.recv(1024)
          recvd_size += len(data)
        else:
          data = sock.recv(1024)
          recvd_size = filesize
        fp.write(data)
      fp.close()
    sock.close()
    break


if __name__ == '__main__':
  socket_service()

解析:

发送者代码:

还是先创建TCP套接字,并发起连接:

具体代码如下:

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 6666))
  except socket.error as msg:
    print(msg)
    print(sys.exit(1))

接下来的While循环中,就开始进行图片发送

  • 通过struct库进行打包,然后再用套接字来发送
  • 注意:网络上的有些代码是不能直接用的,比如在这里,就需要把str变成bytes
  • 通过os库来获取文件的基本名(这个是为了避免有些文件中包含具体路径)
  • 通过os库来获取文件的大小(通过文件状态中关于大小的描述中获取到)
fhead = struct.pack(b'128sl', bytes(os.path.basename(filepath), encoding='utf-8'), os.stat(filepath).st_size)
s.send(fhead)

之后再通过二进制方式来获取文件。
然后再发送出去,每次发送固定长度的数据。先读,再判断是否为空,再发送。

接受端:

还是一样,先创建套接字(不过这个需要绑定对应的ip以及端口)
具体代码如下:(这里写的是监听10个套接字对象,但是在我们代码中并没哟用到)

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('127.0.0.1', 6666))
    s.listen(10)
  except socket.error as msg:
    print(msg)
    sys.exit(1)

之后就进入到循环,来判断,是否获取到sock对象,这里是会进入阻塞状态的。

deal_data中就开始通过连接的对象来获取数据。

一样,还是一个无限循环,但其实本质上还是空的。。。没什么特别的。

之后就是对于传过来的文件名处理一下,这里的这些“128sl”,其实就是一个大小规模(类似于打包的箱子大小的样子)。然后就是得到新的文件名了。
对应的代码如下:

filename, filesize = struct.unpack('128sl', buf)
fn = filename.decode().strip('\x00')
new_filename = os.path.join('./', 'new_' + fn)

之后的recvd_size,其实就是为了来计数的标签
之后就不断地收,边收边写入文件,一直到收完了之后。就关闭掉对应的文件流
最后关闭套接字,退出循环

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用python分析git log日志示例
Feb 27 Python
python简单的函数定义和用法实例
May 07 Python
Python利用pandas计算多个CSV文件数据值的实例
Apr 19 Python
Python3中的列表生成式、生成器与迭代器实例详解
Jun 11 Python
matplotlib给子图添加图例的方法
Aug 03 Python
解决安装python库时windows error5 报错的问题
Oct 21 Python
Python读取csv文件实例解析
Dec 30 Python
pytorch方法测试——激活函数(ReLU)详解
Jan 15 Python
python实现的分层随机抽样案例
Feb 25 Python
Python 通过正则表达式快速获取电影的下载地址
Aug 17 Python
基于python+selenium自动健康打卡的实现代码
Jan 13 Python
Python实现归一化算法详情
Mar 18 Python
python实现udp传输图片功能
Mar 20 #Python
python实现UDP协议下的文件传输
Mar 20 #Python
python实现TCP文件传输
Mar 20 #Python
python实现FTP循环上传文件
Mar 20 #Python
python实现ftp文件传输功能
Mar 20 #Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
Mar 20 #Python
python实现FTP文件传输的方法(服务器端和客户端)
Mar 20 #Python
You might like
站长助手-网站web在线管理程序 v1.0 下载
2007/05/12 PHP
php根据日期判断星座的函数分享
2014/02/13 PHP
php中preg_replace正则替换用法分析【一次替换多个值】
2017/01/17 PHP
Yii2框架加载css和js文件的方法分析
2019/05/25 PHP
javascript判断office版本示例
2014/04/11 Javascript
触屏中的JavaScript事件分析
2015/02/06 Javascript
jQuery实现的登录浮动框效果代码
2015/09/26 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
解析利用javascript如何判断一个数为素数
2016/12/08 Javascript
Angularjs中三种数据的绑定策略(“@”,“=”,“&”)
2016/12/23 Javascript
Vue2.x中的父组件传递数据至子组件的方法
2017/05/01 Javascript
JavaScript中各数制转换全面总结
2017/08/21 Javascript
详解vue.js数据传递以及数据分发slot
2018/01/20 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
JS根据Unix时间戳显示发布时间是多久前【项目实测】
2019/07/10 Javascript
Python中的类与对象之描述符详解
2015/03/27 Python
利用Python的装饰器解决Bottle框架中用户验证问题
2015/04/24 Python
python中私有函数调用方法解密
2016/04/29 Python
利用Python批量生成任意尺寸的图片
2016/08/29 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
2019/06/25 Python
python sorted方法和列表使用解析
2019/11/18 Python
Python count函数使用方法实例解析
2020/03/23 Python
python 制作网站筛选工具(附源码)
2021/01/21 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
全球酒店比价网:HotelsCombined
2017/06/20 全球购物
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
Kappa英国官方在线商店:服装和运动器材
2020/11/22 全球购物
电子信息专业自荐书
2014/02/04 职场文书
餐饮投资计划书
2014/04/25 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
2015年社区服务活动总结
2015/03/25 职场文书
消防演习通知
2015/04/25 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
2016年三八红旗手先进事迹材料
2016/02/26 职场文书
分布式架构Redis中有哪些数据结构及底层实现原理
2022/03/13 Redis