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
使用TCP套接字下载python中的文件_Python_Sockets_Tcp_Concurrency_Concurrent Programming - Fatal编程技术网

使用TCP套接字下载python中的文件

使用TCP套接字下载python中的文件,python,sockets,tcp,concurrency,concurrent-programming,Python,Sockets,Tcp,Concurrency,Concurrent Programming,我正在编写一个TCP并发(基于进程的并发)服务器,它接受下载命令。客户端应该从服务器下载一个文件,从现在开始,我已经硬编码了文件名以下载,以便测试我的下载算法 我查找了一个示例,正在使用代码中使用的while循环 我认为我的问题是其中一个while循环(或者可能两个循环)被挂起并且不会结束。我相信这是客户端,它可能正在等待更多的文件内容 服务器 file = open('download.txt','rb+') print "Opened File

我正在编写一个TCP并发(基于进程的并发)服务器,它接受下载命令。客户端应该从服务器下载一个文件,从现在开始,我已经硬编码了文件名以下载,以便测试我的下载算法

我查找了一个示例,正在使用代码中使用的while循环

我认为我的问题是其中一个while循环(或者可能两个循环)被挂起并且不会结束。我相信这是客户端,它可能正在等待更多的文件内容

服务器

            file = open('download.txt','rb+')
            print "Opened File: " , file.name

            fileContent = file.read(1)
            clientsocket.send(fileContent)
            while (fileContent):
                print "iteration", fileContent
                clientsocket.send(fileContent)
                fileContent = file.read(1)                  
            file.close()
客户端

    print "Attempting download..."
    f = open('downloaded.txt' , 'wb+')      
    print "Opened File: " , f.name
    fileContent = s.recv(1)
    while (fileContent):
        print "iteration", fileContent
        f.write(fileContent)
        fileContent = s.recv(1)
    print "Download Complete"
    f.close()
我已经完成了无需while循环的文件传输,使用的代码如下

 f.open(file)
 fContent = f.read(1024)
 client.send(fContent)
 f.close

 f.open(file)
 fContent = server.recv(1024)
 f.write(fContent)
 f.close 
但我知道,如果文件大于缓冲区大小,这会导致问题

这是一个并发服务器,它使用单个进程来处理每个连接。(我不认为这会影响我当前的问题,但我对并发性还不熟悉,我想我会提到它。)

有人知道为什么我的while循环没有结束吗?或者有人知道我可能做错了什么吗?提前谢谢

编辑:

我的输出:

cli

服务

客户机卡住了,我必须按住ctrl键将其关闭。服务器将继续接受连接。我刚刚意识到我可以在服务器的while循环之后添加一个简单的print语句来检查服务器的while循环是否完成

第二次编辑:

服务器未挂起(它在循环后成功显示消息)。这让我相信客户端正在调用recv()并等待更多的文件内容

第三次编辑:


出于测试目的,读/写缓冲区仅为1。

逐字节发送文件可能非常慢。最好使用shutil.copyfileobj,它为您处理传输:

def send_file(socket, filename):
    with open('download.txt','rb') as inp:
        print "Opened File: " , file.name
        out = socket.makefile('wb')
        shutil.copyfileobj(inp, out)

def recv_file(socket, filename):
    with open('download.txt','wb') as out:
        print "Opened File: " , file.name
        inp = socket.makefile('rb')
        shutil.copyfileobj(inp, out)

这比我正在尝试做的要有用得多,但是我想在上面完成它。这是一个学校项目,我正在尽可能模仿“c”,我不相信“c”有这样的调用:(在服务器端,你不关闭套接字,所以客户端不知道文件结束了。添加
clientsocket.shutdown(socket.SOCK\RDWR)
然后
clientsocket.close()
@tdelaney服务器应该继续接受命令。我不希望在下载完成后连接终止,如果我关闭套接字,会不会发生这种情况?是的,它会终止。但是如果你想保持套接字打开,你会遇到更大的问题,因为你仍然需要一种方法来告诉客户端传输已完成。一种常见的方法是使用
struct
模块来定义消息结构(例如,一个标志字段来说明这是否是最后一个片段加上长度)然后是文件的精确长度字节。客户端将读取标题,然后读取精确长度字节并重复,直到标志显示停止。您也从未真正关闭
f.close->f.close()
Recived  dl from:  ('127.0.0.1', 38161)  |  2015-12-06 13:07:12.835998
Opened File:  download.txt
iteration t
iteration h
iteration i
iteration s
iteration
iteration i
iteration s
iteration
iteration a
iteration
iteration f
iteration i
iteration l
iteration e
iteration
def send_file(socket, filename):
    with open('download.txt','rb') as inp:
        print "Opened File: " , file.name
        out = socket.makefile('wb')
        shutil.copyfileobj(inp, out)

def recv_file(socket, filename):
    with open('download.txt','wb') as out:
        print "Opened File: " , file.name
        inp = socket.makefile('rb')
        shutil.copyfileobj(inp, out)