将多个文件从一台主机传输到另一台主机

海伦

我是 python 套接字编程的新手。我想将 5 个文件(照片)从 mininet 中的一台主机传输到另一台主机。这些文件的名称分别编号(我的意思是 1.jpg、2.jpg 和 ...)。问题是,当我运行这些代码时,第一张照片传输正确,但其他照片已损坏。有什么问题:

发件人.py

import socket
import sys

buf = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.0.0.1',12345))

for i in range(1,6):
    with open("%d.jpg" % (i),'rb') as f:
        data = f.read(buf)
        while 1:
            if not data:
                break
            s.sendall(data)
            data = f.read(buf)
s.close()

接收器.py:

import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('10.0.0.1', 12345))

buf = 1024

s.listen(1)
conn , addr = s.accept()
for i in range(6,11):
    with open("%d.jpg" % (i),'wb') as f:
        while 1:
            data = conn.recv(buf)
            #print(data[:10])
            #print "PACKAGE RECEIVED..."
            f.write(data)
            if not data: break
#conn.close()
#s.close()
PM 2环

解决问题的简单方法是为每个文件创建一个新连接。下面的代码就是这样做的。

发件人

from __future__ import print_function
import socket

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

def send_file(fname):
    with open(fname, 'rb') as f:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((HOST, PORT))
        except socket.error as err:
            print(err, HOST, PORT)
            sock.close()
            return

        while True:
            data = f.read(BUFSIZE)
            if not data:
                break
            while data:
                sent = sock.send(data)
                data = data[sent:]

    sock.close()

fnames = [
    'test0.jpg',
    'test1.jpg',
    'test2.jpg',
    'test3.jpg',
]

def main():
    for fname in fnames:
        send_file(fname)

if __name__ == '__main__':
    main()

接收者

from __future__ import print_function
import socket

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

class Receiver:
    ''' Buffer binary data from socket conn '''
    def __init__(self, conn):
        self.conn = conn
        self.buff = bytearray()

    def get(self, size):
        ''' Get size bytes from the buffer, reading
            from conn when necessary 
        '''
        while len(self.buff) < size:
            data = self.conn.recv(BUFSIZE)
            if not data:
                break
            self.buff.extend(data)
        # Extract the desired bytes
        result = self.buff[:size]
        # and remove them from the buffer
        del self.buff[:size]
        return bytes(result)

    def save(self, fname):
        ''' Save the remaining bytes to file fname '''
        with open(fname, 'wb') as f:
            if self.buff:
                f.write(bytes(self.buff))
            while True:
                data = self.conn.recv(BUFSIZE)
                if not data:
                    break
                f.write(data)

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.bind((HOST, PORT))
    except socket.error as err:
        print('Bind failed', err)
        return

    sock.listen(1)
    print('Socket now listening at', HOST, PORT)
    file_number = 0
    try:
        while True:
            conn, addr = sock.accept()
            print('Connected with', *addr)

            fname = 'image%d.jpg' % file_number
            with open(fname, 'wb') as f:
                while True:
                    data = conn.recv(BUFSIZE)
                    if not data:
                        break
                    f.write(data)
            conn.close()
            print(fname, 'saved\n')
            file_number += 1

    # Hit Break / Ctrl-C to exit
    except KeyboardInterrupt:
        print('\nClosing')

    sock.close()

if __name__ == '__main__':
    main()

您需要点击CtrlCBreak(取决于您的操作系统)退出接收器。


但是在接收器上使用这些数字文件名并不是很令人满意,所以我决定让它更复杂一些。:) 在以下版本中,我们在文件数据之前发送文件名。这有点棘手,因为接收器需要将文件名与实际文件数据分开。如果每个socket.recv调用对应一个socket.send调用,这很容易,但不能保证一定会发生:接收的字节可能与发送的方式不同。接收器需要缓冲字节,以便正确分解它们。有关详细信息,请参阅套接字编程 HOWTO

为了让接收者知道文件名的结尾,我们首先发送一个对文件名长度进行编码的字节。一个字节可以容纳 0 到 255 之间的数字,因此此代码无法处理超过此长度的文件名。在长度字节之后,我们发送使用 UTF-8 编码的文件名本身。然后我们发送实际的文件内容。

接收器使用名为 Receiver 的类来处理缓冲。这个类有一个.get方法,我们可以用它来获取指定数量的字节。我们使用该方法来获取文件名长度和文件名。然后我们使用Receiver的.save方法将接收到的文件内容保存到一个新文件中。

这段代码有点乱,因为它旨在以任意组合在 Python 2 和 Python 3 上运行。如果仅用于 Python 3,它会更整洁一些。我将“localhost”硬编码为主机名,因为我只有一台计算机,所以我无法通过网络对其进行测试,但我相信它可以在网络上正常工作。

这是发件人:

from __future__ import print_function
import socket
from struct import pack

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

def send(sock, data):
    while data:
        sent = sock.send(data)
        data = data[sent:]

def send_file(fname):
    with open(fname, 'rb') as f:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((HOST, PORT))
        except socket.error as err:
            print(err, HOST, PORT)
            sock.close()
            return

        # Send the file name length & the filename itself in one packet          
        send(sock, pack('B', len(fname)) + fname.encode())
        while True:
            data = f.read(BUFSIZE)
            if not data:
                break
            send(sock, data)

    sock.close()

fnames = [
    'test1.gif',
    'test2.jpg',
    'test3.png',
    'test4.pdf',
]

def main():
    for fname in fnames:
        send_file(fname)

if __name__ == '__main__':
    main()

这是接收器:

from __future__ import print_function
import socket
from struct import unpack

HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096

class Receiver:
    ''' Buffer binary data from socket conn '''
    def __init__(self, conn):
        self.conn = conn
        self.buff = bytearray()

    def get(self, size):
        ''' Get size bytes from the buffer, reading
            from conn when necessary 
        '''
        while len(self.buff) < size:
            data = self.conn.recv(BUFSIZE)
            if not data:
                break
            self.buff.extend(data)
        # Extract the desired bytes
        result = self.buff[:size]
        # and remove them from the buffer
        del self.buff[:size]
        return bytes(result)

    def save(self, fname):
        ''' Save the remaining bytes to file fname '''
        with open(fname, 'wb') as f:
            if self.buff:
                f.write(bytes(self.buff))
            while True:
                data = self.conn.recv(BUFSIZE)
                if not data:
                    break
                f.write(data)

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.bind((HOST, PORT))
    except socket.error as err:
        print('Bind failed', err)
        return

    sock.listen(1)
    print('Socket now listening at', HOST, PORT)
    try:
        while True:
            conn, addr = sock.accept()
            print('Connected with', *addr)
            # Create a buffer for this connection
            receiver = Receiver(conn)
            # Get the length of the file name
            name_size = unpack('B', receiver.get(1))[0] 
            # Get the file name itself
            name = receiver.get(name_size).decode()
            print('name', name)
            # Save the file
            receiver.save(name)
            conn.close()
            print('saved\n')
    # Hit Break / Ctrl-C to exit
    except KeyboardInterrupt:
        print('\nClosing')

    sock.close()

if __name__ == '__main__':
    main()

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用脉冲编码调制将数据从一台PC传输到另一台PC

来自分类Dev

如何将Umbraco CMS从一台PC传输到另一台PC

来自分类Dev

在将文件从一台PC传输到另一台PC时更改可执行文件(* .exe)的大小

来自分类Dev

将数百万个文件从一台服务器传输到另一台服务器

来自分类Dev

文件(可能是最新的)如何将Git存储库从一台PC传输到另一台PC?

来自分类Dev

如何将文件从一台服务器传输到另一台服务器?

来自分类Dev

如何将文件从一台服务器传输到另一台服务器?

来自分类Dev

将数百万个文件从一台服务器传输到另一台服务器

来自分类Dev

将大约300GB的文件从一台服务器传输到另一台服务器

来自分类Dev

每天将文件夹从一台SFTP服务器传输到另一台SFTP服务器

来自分类Dev

使用蓝牙将文件传输到另一台iOS设备

来自分类Dev

在Linux上将数据包从一台主机路由到另一台主机

来自分类Dev

在将端口从一台主机转发到另一台主机的同时维护源IP,但是存在一个小问题

来自分类Dev

MongoDB:使用mongo shell将选定的数据从一台主机/计算机复制到另一台主机/计算机

来自分类Dev

SSH ProxyCommand一台主机访问另一台主机

来自分类Dev

如何将Cookie的一台主机设置为另一台主机

来自分类Dev

如何将Cookie的一台主机设置为另一台主机

来自分类Dev

如何通过网络将java .class从一台计算机传输到另一台计算机?

来自分类Dev

错误1045:将SQL数据库从一台服务器传输到另一台服务器

来自分类Dev

将RAM从一台笔记本电脑传输到另一台笔记本电脑

来自分类Dev

如何将实时视频从一台PC流传输到另一台PC上的Apache服务器

来自分类Dev

如何将传输配置传输到另一台机器?

来自分类Dev

从第三台计算机启动将文件从一台服务器传输到另一台服务器

来自分类Dev

如何访问Docker内部的另一台主机?

来自分类Dev

访问为另一台主机注册的变量

来自分类Dev

使用主机文件将主机名定向到局域网内的另一台计算机

来自分类Dev

将Cookie传输到Chrome上的另一台设备

来自分类Dev

将Python代码传输到另一台计算机-停止工作

来自分类Dev

将SSD传输到另一台计算机是否安全?

Related 相关文章

  1. 1

    使用脉冲编码调制将数据从一台PC传输到另一台PC

  2. 2

    如何将Umbraco CMS从一台PC传输到另一台PC

  3. 3

    在将文件从一台PC传输到另一台PC时更改可执行文件(* .exe)的大小

  4. 4

    将数百万个文件从一台服务器传输到另一台服务器

  5. 5

    文件(可能是最新的)如何将Git存储库从一台PC传输到另一台PC?

  6. 6

    如何将文件从一台服务器传输到另一台服务器?

  7. 7

    如何将文件从一台服务器传输到另一台服务器?

  8. 8

    将数百万个文件从一台服务器传输到另一台服务器

  9. 9

    将大约300GB的文件从一台服务器传输到另一台服务器

  10. 10

    每天将文件夹从一台SFTP服务器传输到另一台SFTP服务器

  11. 11

    使用蓝牙将文件传输到另一台iOS设备

  12. 12

    在Linux上将数据包从一台主机路由到另一台主机

  13. 13

    在将端口从一台主机转发到另一台主机的同时维护源IP,但是存在一个小问题

  14. 14

    MongoDB:使用mongo shell将选定的数据从一台主机/计算机复制到另一台主机/计算机

  15. 15

    SSH ProxyCommand一台主机访问另一台主机

  16. 16

    如何将Cookie的一台主机设置为另一台主机

  17. 17

    如何将Cookie的一台主机设置为另一台主机

  18. 18

    如何通过网络将java .class从一台计算机传输到另一台计算机?

  19. 19

    错误1045:将SQL数据库从一台服务器传输到另一台服务器

  20. 20

    将RAM从一台笔记本电脑传输到另一台笔记本电脑

  21. 21

    如何将实时视频从一台PC流传输到另一台PC上的Apache服务器

  22. 22

    如何将传输配置传输到另一台机器?

  23. 23

    从第三台计算机启动将文件从一台服务器传输到另一台服务器

  24. 24

    如何访问Docker内部的另一台主机?

  25. 25

    访问为另一台主机注册的变量

  26. 26

    使用主机文件将主机名定向到局域网内的另一台计算机

  27. 27

    将Cookie传输到Chrome上的另一台设备

  28. 28

    将Python代码传输到另一台计算机-停止工作

  29. 29

    将SSD传输到另一台计算机是否安全?

热门标签

归档