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 相关文章推荐
简单的通用表达式求10乘阶示例
Mar 03 Python
python中Flask框架简单入门实例
Mar 21 Python
基于Python打造账号共享浏览器功能
May 30 Python
利用Python进行图像的加法,图像混合(附代码)
Jul 14 Python
Python笔记之观察者模式
Nov 20 Python
Python列表切片常用操作实例解析
Dec 16 Python
Python基于codecs模块实现文件读写案例解析
May 11 Python
Python collections.defaultdict模块用法详解
Jun 18 Python
openCV提取图像中的矩形区域
Jul 21 Python
OpenCV利用python来实现图像的直方图均衡化
Oct 21 Python
Python实现JS解密并爬取某音漫客网站
Oct 23 Python
python实现学员管理系统(面向对象版)
Jun 05 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
基于Windows下Apache PHP5.3.1安装教程
2010/01/08 PHP
PHP使用file_get_content设置头信息的方法
2016/02/14 PHP
php实现压缩合并js的方法【附demo源码下载】
2016/09/22 PHP
PHP实现普通hash分布式算法简单示例
2018/08/06 PHP
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
2014/05/20 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
实现easyui的datagrid导出为excel的示例代码
2016/11/10 Javascript
js中的面向对象入门
2017/03/06 Javascript
使用jQuery卸载全部事件的思路详解
2017/04/03 jQuery
jQuery实现的淡入淡出图片轮播效果示例
2018/08/29 jQuery
Angular2之二级路由详解
2018/08/31 Javascript
详解微信小程序文件下载--视频和图片
2019/04/24 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
2019/10/27 Javascript
通过Kettle自定义jar包供javascript使用
2020/01/29 Javascript
[03:17]DOTA2-DPC中国联赛1月29日Recap集锦
2021/03/11 DOTA
Python实现二叉堆
2016/02/03 Python
机器学习10大经典算法详解
2017/12/07 Python
PyQt5每天必学之弹出消息框
2018/04/19 Python
python3实现SMTP发送邮件详细教程
2018/06/19 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
python3实现名片管理系统
2020/11/29 Python
浅谈python中统计计数的几种方法和Counter详解
2019/11/07 Python
python如何调用java类
2020/07/05 Python
Python接口自动化测试框架运行原理及流程
2020/11/30 Python
CSS3实现背景透明文字不透明的示例代码
2018/06/25 HTML / CSS
英国最大的户外商店:Go Outdoors
2019/04/17 全球购物
C#面试题
2016/05/06 面试题
医院后勤自我鉴定
2013/10/13 职场文书
实习生单位鉴定意见
2013/12/04 职场文书
简历中个人自我评价范文
2013/12/26 职场文书
房地产销售经理岗位职责
2014/01/01 职场文书
开办加工厂创业计划书
2014/01/03 职场文书
圣贤教育改变命运观后感
2015/06/16 职场文书
2015年除四害工作总结
2015/07/23 职场文书
护士旷工检讨书
2015/08/15 职场文书
员工给公司的建议书
2019/06/24 职场文书