如何在不关闭tcp套接字的情况下发送文件结尾

时间:2015-05-08 15:56:37

标签: python sockets tcp sendfile

我正在尝试通过python中编码的对等聊天系统中的tcp套接字发送文件。接收套接字似乎不知道没有更多文件可以接收。我可以让接收套接字不预期未来的数据的唯一方法是关闭发送套接字(使用socket.shutdown(socket.SHUT_WR))。但是,关闭发送套接字不是一个选项,因为我需要该套接字来发送其他消息。我fisrt尝试为文件发送/接收分配一个新端口并失败。现在,我已经尝试创建一个文件结尾“signal”,但它不会在接收端被识别为与tcp段分开的消息,所以我被卡住了。

发送代码如下所示:

def sendFile(self,filePath):
    try:
        f = open(filePath, 'rb')
        print 'file opened'
        for soc in self.allClients.keys():
            try:
                f = open(filePath, 'rb')
            except:
                print "File does not exist"
            print 'Sending File: ' + filePath
            l = f.read(1024)
            while (l):
                print 'Sending...'
                soc.send(l)
                l = f.read(1024)
            soc.send('end')
            f.close()
            print 'File sent'                
    except:
        print "File does not exist"

接收代码如下所示:

 def receiveFile(self, ext, clientsoc):   
    f = open('receivedFile' + ext,'wb')

    print "Receiving File..."
    l = clientsoc.recv(1024)
    while(l):
        print "Receiving..."
        if (l is not 'end'):
            f.write(l)   
            print l + '\n'
            l = clientsoc.recv(1024)
        else:
            break
    f.close()
    print "Received Fileeeeeooooo"

更奇怪的是,当我在同行程序之外使用它时,此代码可以正常工作。任何帮助将不胜感激,我已经在这两天苦苦挣扎。

3 个答案:

答案 0 :(得分:3)

首先,您不得将字符串与isis not进行比较:

>>> a = "he"
>>> a + "llo" is "hello"
False

其次,TCP是一种流媒体协议。 recv最多可达1024个字节,但可能更少,如果您从服务器发送两个部分,它们可以合并为一个recv。因此l不太可能是"end",而是“文件结尾的最后一个字节”。如果您检查"end",则不允许"end"位于文件中。最佳解决方案是首先发送文件的长度,然后发送和recv length字节。

PS:你可能想在服务器端使用sendall

答案 1 :(得分:0)

首先发送文件大小!!

新代码看起来像这样。

发送代码:

def sendFileOrImage(self,path):

    name, ext = os.path.splitext(path)
    filesize = str(os.path.getsize(path))
    message = filesize + ',' + ext
    print 'message'
    for client in self.allClients.keys():
        client.send(message)
        self.sendFile(path)

def sendFile(self,filePath):
    try:
        f = open(filePath, 'rb')
    except:
        print "File does not exist"
    print 'Sending File: ' + filePathty
    for soc in self.allClients.keys():
        l = f.read(1024)
        while (l):
            print 'Sending...'
            soc.send(l)
            l = f.read(1024)
        f.close()
        print 'File sent'

接收代码:

def receiveFile(self,ext, filesize, clientsoc):   
    total = 0
    f = open('receivedFile' + ext,'wb')

    print "Receiving File..."
    l = clientsoc.recv(1024)
    total = len(l)
    while(l):
        print "Receiving..."

        f.write(l) 
        if (str(total) != filesize):
            print 'trying to receive'
            l = clientsoc.recv(1024)
            total = total + len(l)
        else:
            break
    f.close()
    print "Received Fileeeeeooooo"

感谢大家的帮助!

答案 2 :(得分:0)

您的接收代码有效,但仍有一个问题需要您尽快解决。如果您的文件大小低于 1024,您的套接字将一直监听,为了解决这个问题,您需要像下面这样更改代码。

def receiveFile(self,ext, filesize, clientsoc):   
    total = 0
    f = open('receivedFile' + ext,'wb')
    print("Receiving File...")
    l = clientsoc.recv(1024)
    total = len(l)
    while(l):
        print("Receiving...")
        f.write(l) 
        if (str(total) != filesize):
            print 'trying to receive'
            l = clientsoc.recv(1024)
            total = total + len(l)
        if(int(total)>= int(filesize)):
            break
    f.close()
    print("Received Fileeeeeoooo")