使用Python通过TCP传输文件

时间:2013-10-16 19:26:28

标签: python sockets tcp

我是python的新手,发现尝试理解如何使用带有tcp连接的套接字发送文件非常困难 我在另一个似乎有用的问题中找到了这段代码

客户端

def _sendFile(self, path):
    sendfile = open(path, 'rb')
    data = sendfile.read()

    self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
    self._con.sendall(data)


    # Get Acknowledgement
    self._con.recv(1) # Just 1 byte

服务器端

def _recieveFile(self, path):
    LENGTH_SIZE = 4 # length is a 4 byte int.
    # Recieve the file from the client
    writefile = open(path, 'wb')
    length = decode_length(self.con.read(LENGTH_SIZE) # Read a fixed length integer, 2 or 4 bytes
    while (length):
        rec = self.con.recv(min(1024, length))
        writefile.write(rec)
        length -= sizeof(rec)

    self.con.send(b'A') # single character A to prevent issues with buffering

现在我对这段代码有两个问题 首先

self._con.sendall(encode_length(len(data)))

在这一行中它给出了一个错误,提示encode_length是未定义的

其次这些是发送和接收文件的函数 我在哪里打电话给他们 我首先形成TCP连接然后调用这些函数 如何直接调用它们,如果我直接调用它,它会在客户端给我一个错误,说_sendFile(self,path)有两个参数(因为我不是只传递自己的路径)

第三,我使用os库中的函数来获取完整路径,所以我调用的函数就像

_sendFile(os.path.abspath("file_1.txt"))

这是传递参数的正确方法

对不起,我知道这个问题非常基本而且很蹩脚,但到处都是网上我基本上可以得到这个功能而不是怎么称呼它

现在这就是我调用函数的方式

serverIP = '192.168.0.102'
serverPort = 21000

clientSocket = socket(AF_INET, SOCK_STREAM)

message = "Want to Backup a Directory"


clientSocket.connect((serverIP, serverPort))

_sendFile(os.path.abspath("file_1.txt"))

这基本上是错误的

我为客户端和服务器使用相同的计算机

使用终端

在Ubuntu上运行Python

1 个答案:

答案 0 :(得分:3)

第一个问题:

这是因为您还没有定义函数encode/decode_lenght


第二个问题:

您的职能是:def _sendFile(self, path): ... 你知道如何使用self吗?它在课堂上使用。因此,在没有self的情况下定义它,或者使用类:

实施例

from socket import *
class Client(object):

    def __init__(self):

        self.clientSocket = socket(AF_INET, SOCK_STREAM)

    def connect(self, addr):

        self.clientSocket.connect(addr)

    def _sendFile(self, path):

        sendfile = open(path, 'rb')
        data = sendfile.read()

        self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
        self._con.sendall(data)


        # Get Acknowledgement
        self._con.recv(1) # Just 1 byte

>>> client = Client()
>>> client.connect(("192.168.0.102", 21000))
>>> client._sendFile(os.path.abspath("file_1.txt")) # If this file is in your current directory, you may just use "file_1.txt"

同样(几乎)Server


在哪里定义这些功能?在代码中!你的职能应该做什么? 好的,一个例子:

def encode_length(l):

    #Make it 4 bytes long
    l = str(l)
    while len(l) < 4:
        l = "0"+l 
    return l

# Example of using
>>> encode_length(4)
'0004'
>>> encode_length(44)
'0044'
>>> encode_length(444)
'0444'
>>> encode_length(4444)
'4444'

关于自我:

一点点:

self重定向到您当前的对象,例如:

class someclass:
    def __init__(self):
        self.var = 10
    def get(self):
        return self.var

>>> c = someclass()
>>> c.get()
10
>>> c.var = 20
>>> c.get()
20
>>> someclass.get(c)
20
>>>

someclass.get(c)如何运作? 在执行someclass.get(c)时,我们未创建someclass的新实例 。 当我们从.get()实例调用someclass时,自动self设置为我们的实例对象。所以someclass.get(c) == c.get() 如果我们尝试执行someclass.get(),则self 定义,因此会引发错误: TypeError: unbound method get() must be called with someclass instance as first argument (got nothing instead)


您可以使用装饰器来调用类的函数(而不是它的实例!):

class someclass:
    def __init__(self):
        self.var = 10
    def get(self):
        return 10 # Raises an error
    @classmethod
    def get2(self):
        return 10 # Returns 10!

对不起我的错误解释,我的英语不完美


以下是一些链接:

server.py

client.py