Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在不关闭tcp套接字的情况下发送文件结尾_Python_Sockets_Tcp_Sendfile - Fatal编程技术网

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

Python 如何在不关闭tcp套接字的情况下发送文件结尾,python,sockets,tcp,sendfile,Python,Sockets,Tcp,Sendfile,我试图在一个用python编码的点对点聊天系统中通过tcp套接字发送一个文件。接收套接字似乎不知道没有更多的文件要接收。我可以让接收套接字不预期不来的数据的唯一方法是关闭发送套接字(使用socket.shutdown(socket.shutdown_-WR))。但是,关闭发送套接字不是一个选项,因为我需要该套接字来发送其他消息。我第一次尝试为文件发送/接收分配新端口,但失败。现在,我已经尝试创建一个文件结尾的“信号”,但是它在接收端没有被识别为与tcp段分离的消息,所以我被卡住了 发送代码如下所

我试图在一个用python编码的点对点聊天系统中通过tcp套接字发送一个文件。接收套接字似乎不知道没有更多的文件要接收。我可以让接收套接字不预期不来的数据的唯一方法是关闭发送套接字(使用socket.shutdown(socket.shutdown_-WR))。但是,关闭发送套接字不是一个选项,因为我需要该套接字来发送其他消息。我第一次尝试为文件发送/接收分配新端口,但失败。现在,我已经尝试创建一个文件结尾的“信号”,但是它在接收端没有被识别为与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"
接收代码如下所示:

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"

更奇怪的是,当我在我的同级程序之外使用它时,这个代码可以工作。非常感谢您的帮助,我已经为此挣扎了两天。

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

>>> a = "he"
>>> a + "llo" is "hello"
False
第二,TCP是一种流协议
recv
最多有1024个字节,但可能会更少,如果您从服务器发送两个片段,它们可以合并为一个
recv
。所以
l
不太可能是
“end”
,而是“文件结尾的最后一个字节”。如果您检查
“end”
,则文件中不允许出现
“end”
。最好的解决方案是先发送文件的长度,然后发送和接收
length
bytes


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

先发送文件大小就行了

新代码如下所示

发送代码:

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"

谢谢大家的帮助

您的接收代码可以正常工作,但仍有一个问题需要您快速解决。如果文件大小小于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")

解决此问题的一种更典型的方法是在开始发送文件之前发送文件的长度。这样,就不用担心您发送的文件是否包含文件结束信号。如果有时数据没有通过“线路”传输,会发生什么情况,
recv
是否是阻塞调用?我的意思是当它将返回一个
0
?好的,这里有了它是的,这就是正在发生的事情,“end”只是被附加到最后一个“l”段。谢谢,我会试试的!