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的chardet库获得文件编码并修改编码
Jan 22 Python
简单介绍Python的Tornado框架中的协程异步实现原理
Apr 23 Python
Python中第三方库Requests库的高级用法详解
Mar 12 Python
Python实现动态加载模块、类、函数的方法分析
Jul 18 Python
python 3调用百度OCR API实现剪贴板文字识别
Sep 04 Python
python通过zabbix api获取主机
Sep 17 Python
Django使用paginator插件实现翻页功能的实例
Oct 24 Python
浅谈Python爬虫基本套路
Mar 25 Python
手把手教你Python yLab的绘制折线图的画法
Oct 23 Python
django form和field具体方法和属性说明
Jul 09 Python
多个版本的python共存时使用pip的正确做法
Oct 26 Python
Python音乐爬虫完美绕过反爬
Aug 30 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
PHP字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
php 使用array函数实现分页
2015/02/13 PHP
php 伪造HTTP_REFERER页面URL来源的三种方法
2016/09/22 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
javascript通过class来获取元素实现代码
2013/02/20 Javascript
理解Javascript闭包
2013/11/01 Javascript
引入autocomplete组件时JS报未结束字符串常量错误
2014/03/19 Javascript
JavaScript中String.match()方法的使用详解
2015/06/06 Javascript
javascript的变量、传值、传址、参数之间关系
2015/07/26 Javascript
扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
2017/02/21 Javascript
自带气泡提示的vue校验插件(vue-verify-pop)
2017/04/07 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
2017/04/12 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
发布订阅模式在vue中的实际运用实例详解
2019/06/09 Javascript
vue element-ui读取pdf文件的方法
2019/11/26 Javascript
Python中super关键字用法实例分析
2015/05/28 Python
详解python中字典的循环遍历的两种方式
2017/02/07 Python
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
python numpy存取文件的方式
2020/04/01 Python
python 视频逐帧保存为图片的完整实例
2019/12/10 Python
详解pandas中iloc, loc和ix的区别和联系
2020/03/09 Python
python实现密度聚类(模板代码+sklearn代码)
2020/04/27 Python
细说CSS3中box属性中的overflow-x属性和overflow-y属性值的效果
2014/07/21 HTML / CSS
美国廉价机票预订网站:Cheapfaremart
2018/04/28 全球购物
Under Armour安德玛英国官网:美国高端运动科技品牌
2018/09/17 全球购物
自我鉴定四大框架
2014/01/17 职场文书
七一党建活动方案
2014/01/28 职场文书
应届毕业生如何写求职信
2014/02/16 职场文书
2014年国庆节演讲稿
2014/09/19 职场文书
中学生自我评价范文
2015/03/03 职场文书
政协委员个人总结
2015/03/03 职场文书
起诉状范本
2015/05/20 职场文书
2016年国庆节假期旅游工作总结
2016/04/01 职场文书
Python实现byte转integer
2021/06/03 Python
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript
win11怎么消除图标小盾牌?win11消除图标小盾牌解决方法
2022/08/05 数码科技