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检测一个对象是否为字符串类的方法
May 21 Python
python函数的5种参数详解
Feb 24 Python
python复制文件到指定目录的实例
Apr 27 Python
详解python Todo清单实战
Nov 01 Python
pycharm运行程序时在Python console窗口中运行的方法
Dec 03 Python
Python cv2 图像自适应灰度直方图均衡化处理方法
Dec 07 Python
python处理两种分隔符的数据集方法
Dec 12 Python
python3实现多线程聊天室
Dec 12 Python
500行代码使用python写个微信小游戏飞机大战游戏
Oct 16 Python
tensorflow没有output结点,存储成pb文件的例子
Jan 04 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
May 10 Python
python爬虫智能翻页批量下载文件的实例详解
Feb 02 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 visitFile()遍历指定文件夹函数
2010/08/21 PHP
yii2中使用Active Record模式的方法
2016/01/09 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
保证JavaScript和Asp、Php等后端程序间传值编码统一
2009/04/17 Javascript
JavaScript constructor和instanceof,JSOO中的一对欢喜冤家
2009/05/25 Javascript
JavaScript 设计模式学习 Singleton
2009/07/27 Javascript
URL地址中的#符号使用说明
2011/02/12 Javascript
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
ExtJS4 动态生成的grid导出为excel示例
2014/05/02 Javascript
JavaScript利用HTML DOM进行文档操作的方法
2016/03/28 Javascript
BootStrap轮播HTML代码(推荐)
2016/12/10 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
Vue 2.5 Level E 发布了: 新功能特性一览
2017/10/24 Javascript
webpack组织模块打包Library的原理及实现
2018/03/10 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
微信小程序自定义对话框弹出和隐藏动画
2018/07/19 Javascript
vue实现键盘输入支付密码功能
2018/08/18 Javascript
解决vue props 拿不到值的问题
2018/09/11 Javascript
python3.3教程之模拟百度登陆代码分享
2014/01/16 Python
Python中import导入上一级目录模块及循环import问题的解决
2016/06/04 Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
2017/09/18 Python
python smtplib模块自动收发邮件功能(二)
2018/05/22 Python
Python 私有化操作实例分析
2019/11/21 Python
Python字典底层实现原理详解
2019/12/18 Python
python实现图像高斯金字塔的示例代码
2020/12/11 Python
Python文件名匹配与文件复制的实现
2020/12/11 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
HTML5之WebGL 3D概述(上)—WebGL原生开发开启网页3D渲染新时代
2013/01/31 HTML / CSS
Origins悦木之源英国官网:雅诗兰黛集团高端植物护肤品牌
2017/11/06 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
出国签证在职证明
2014/01/16 职场文书
20年同学聚会感言
2014/02/03 职场文书
祖国在我心中演讲稿450字
2014/09/05 职场文书
2015年植树节活动总结
2015/02/06 职场文书
JavaScript实现简单计时器
2021/06/22 Javascript
Java网络编程之UDP实现原理解析
2021/09/04 Java/Android