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 相关文章推荐
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
Jan 22 Python
使用Python的Twisted框架实现一个简单的服务器
Apr 16 Python
python中的闭包用法实例详解
May 05 Python
python实现逆波兰计算表达式实例详解
May 06 Python
Python文本统计功能之西游记用字统计操作示例
May 07 Python
python实现根据文件格式分类
Oct 31 Python
python3.6连接mysql数据库及增删改查操作详解
Feb 10 Python
python之生成多层json结构的实现
Feb 27 Python
python中Ansible模块的Playbook的具体使用
May 28 Python
如何在C++中调用Python
May 21 Python
Python 实现定积分与二重定积分的操作
May 26 Python
Django + Taro 前后端分离项目实现企业微信登录功能
Apr 07 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
搜索和替换文件或目录的一个好类--很实用
2006/10/09 PHP
PHP中获取文件扩展名的N种方法小结
2012/02/27 PHP
php中使用cookie来保存用户登录信息的实现代码
2012/03/08 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
浅谈PHP实现大流量下抢购方案
2017/12/15 PHP
用js实现的自定义的对话框的实现代码
2010/03/21 Javascript
多次注册事件会导致一个事件被触发多次的解决方法
2013/08/12 Javascript
JS 去除Array中的null值示例代码
2013/11/20 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
2015/08/10 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
如何快速上手Vuex
2017/02/14 Javascript
理解 javascript 中的函数表达式与函数声明
2017/07/07 Javascript
js与jQuery实现的用户注册协议倒计时功能实例【三种方法】
2017/11/09 jQuery
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
Vue+Openlayers自定义轨迹动画
2020/09/24 Javascript
记一次vue跨域的解决
2020/10/21 Javascript
[00:15]天涯墨客终极技能展示
2018/08/25 DOTA
玩转python爬虫之正则表达式
2016/02/17 Python
教你学会使用Python正则表达式
2017/09/07 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
2019/04/17 Python
Python实现制度转换(货币,温度,长度)
2019/07/14 Python
解决python-docx打包之后找不到default.docx的问题
2020/02/13 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
Python3读写ini配置文件的示例
2020/11/06 Python
python+playwright微软自动化工具的使用
2021/02/02 Python
美国内衣第一品牌:Hanes(恒适)
2016/07/29 全球购物
香奈儿美国官网:CHANEL美国
2020/05/20 全球购物
行政助理的职责
2013/11/14 职场文书
机电工程学生自荐信范文
2013/12/07 职场文书
公司门卫的岗位职责
2014/02/19 职场文书
劳动竞赛活动总结
2014/05/05 职场文书
公开承诺书格式
2014/05/21 职场文书
教师查摆问题自查报告
2014/10/11 职场文书
四风之害观后感
2015/06/09 职场文书
关爱留守儿童主题班会
2015/08/13 职场文书
python某漫画app逆向
2021/03/31 Python