【问题标题】:Multiple clients file transfer in python client-server without threadingpython客户端-服务器中的多个客户端文件传输,无需线程
【发布时间】:2023-06-10 20:04:01
【问题描述】:

我正在尝试多个客户端在一个端口上同时向服务器发送文件(即服务器运行不同的端口并且多个客户端连接到每个端口并发送文件)。我看过几个答案,例如this,但他们使用不同的方法,我只是希望有人能指出我在这里做错了什么,所以我可以使用我更好理解的相同代码。请帮助我:

  1. 为什么我的代码不能用于多文件传输?
  2. 我也在计算吞吐量(即实际文件传输),它是正确的方法吗?

感谢您的帮助。

 ----- server.py ---
import socket,time
import sys, optparse,datetime


#def client(net,src,dst):

#def server(net,src):
print("we are in server ...")


parser = optparse.OptionParser()
parser.add_option('-i',dest='ip',default='')

parser.add_option('-p',dest='port',type='int',default=5001)

parser.add_option('-t',dest='ftype',type='str',default='.txt')
(options,args) = parser.parse_args()

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
host = socket.gethostname()
server_socket.bind((options.ip, options.port))
server_socket.listen(100)

s = datetime.datetime.now().strftime("%d%m%y_%H%M%S")
f = open('.recfile_%s_%s'%(s,options.port)+options.ftype,'wb')
count = 0
while 1:
    client_socket, addr = server_socket.accept()
    start_time = datetime.datetime.now()
    cl_addr = addr[0]
    print 'Got connection from', addr
    print("Receiving ...")
    data = client_socket.recv(1024)
    while(data):
        f.write(data)
        data = client_socket.recv(1024)
        count+=len(data)
        continue
    f.close()
    client_socket.close()
    end_time = datetime.datetime.now()
    total_time = end_time - start_time
    total_time = total_time.total_seconds()
    average_speed = round((1024*count*0.001)/(total_time),3)
    fd = open('server_data.csv','a+')
    fd.write(str(cl_addr)+','+str(start_time)+','+str(end_time)+','+str(total_time)+','+str(average_speed)+','+str(options.port)+'\n\r')
    

fd.close()
server_socket.close() 

客户端

----- client.py -----
import socket
import sys, optparse



#def client(net,src,dst):
print("we are in client ..")

parser = optparse.OptionParser()

parser.add_option('-i',dest='ip',default='')
parser.add_option('-p',dest='port',type='int',default=5001)
parser.add_option('-f',dest='fname',type='str',default='hugefile.txt')
(options,args) = parser.parse_args()

client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_socket.connect((options.ip,options.port))


img_file = options.fname
f = open(img_file,'rb')
data = f.read(1024)

while(data):
    
    client_socket.send(data)
    data = f.read(1024)
f.close()
client_socket.shutdown(socket.SHUT_WR)
client_socket.close()
print "Data Sent successfully!"


【问题讨论】:

    标签: python sockets file-transfer


    【解决方案1】:

    至少存在一个问题:recfile 文件在循环开始之前打开,在循环内部关闭。这意味着从第二次迭代开始,您将尝试在已关闭的文件上写入并获得异常。

    如何避免:with open(...) as ...: 块非常棒,因为它们不仅可以保证在发生错误时正确关闭,而且还可以确保程序中的块结构正确。

    顺便说一句,count 在循环内也应该被重置为 0,并且越接近循环对未来的读者和代码维护者越好

    【讨论】:

    • 谢谢,我已将文件创建移至while 循环,现在正在创建文件,但仍是一个接一个
    • @Tabz:然后尝试在循环之前离开文件创建并在其之后移动关闭。或者更好地使用withwith open() as f while 1: ...
    • 使用with open()帮助完成文件传输但将其从while loop中取出只会为每个连接创建一个文件,因此它应该在内部,因此每个连接创建一个数据文件。你觉得我应该multiprocessing 吗?
    • 我不会将多处理用于 IO 绑定问题,而只是使用多线程或简单地使用 select。您可以找到 here 线程模块的示例。
    • 谢谢大家,我找到了multiprocessing现在发帖的解决方案..
    【解决方案2】:

    我通过即兴创作 this 找到了解决方案。 如果没有multiprocessingmultithreading,则无法与同一个套接字进行多个连接。由于我使用的是 Python 2.7,multithreading 不适合我。

    【讨论】:

    • 如果没有多处理或多线程,就不可能实现到同一个套接字的多个连接。我很抱歉,但这是完全错误的。由于存在select(来自unix BSD 4),因此可以编写没有线程的多客户端服务器。由于 Python 在套接字上提供了 select 接口......