提高了通过套接字发送多个文件的吞吐量



首先,我没有任何错误或bug,我问这个问题是为了了解更多。我想通过从客户端到服务器的单独连接同时发送多个文件。我使用线程使发送过程在客户端并发。听起来它确实稍微提高了吞吐量。但我还是很困惑。下面是我的服务器和客户端代码。我不知道使用线程是如何使这个进程并发的,因为服务器端的套接字有一个队列,所有数据都存储在队列中,无论是依次发送还是并发发送。有人能向我解释一下吗?或者,如果我错了,或者我的代码不能同时发送,请告诉我!谢谢

服务器.py

def rcv_thread(self, conn):
context = ''
while True:
try:
recvfile = conn.recv(4096)
context += recvfile.decode()
except Exception:
if context == '':
return
break

/////////
conn.close()
def receive(self):
self.t = time.time()
while True:
c, addr = self.socket.accept()
c.settimeout(2)
start_new_thread(self.rcv_thread,(c,))

客户.py

def transfer_file(self, file_name):
path = self.path + "/" + file_name
sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sckt.connect((self.HOST, self.PORT))
file = open(path, 'rb')
context = file.read()
sckt.sendall((file_name + "##" + context.decode()).encode())
sckt.close()
def run(self):
self.start_time = time.time()
files = os.listdir(self.path)
num_of_iterates = int(len(files) / self.concurrency)
for j in range(num_of_iterates + 1):
min_iter = min(self.concurrency, len(files) - j * self.concurrency)
for i in range(min_iter):
th = threading.Thread(target=self.transfer_file, args={files[j * self.concurrency + i]})
th.start()
self.connection_threads.append(th)
for i in range(min_iter):
self.connection_threads[i].join()

服务器端的套接字有一个队列,所有数据都存储在队列中,无论是依次发送还是同时发送。

这里涉及多个套接字,而不是一个。在服务器端有一个侦听器套接字,它在accept上返回一个新连接的套接字。类似地,在客户端上使用了多个套接字。这导致客户端和服务器之间有多个TCP连接,每个连接都有自己的发送和接收缓冲区以及独立的流控制。

考虑到TCP连接从飞行中数据的一个小窗口开始,并缓慢地向上倾斜该窗口,通过并行具有许多短寿命的TCP连接,可以更好地利用可用带宽,而不是一个接一个地具有许多短时间的TCP连接。不过,只使用几个长期使用的TCP连接并通过这些连接传输多个文件可能会更高效。

当使用多个线程时,除了网络流量之外,还有其他因素可以提高性能。首先,它更好地利用了当今CPU中的多核。然后,对于每次传输,都会从磁盘读取一个文件,这也会增加延迟——对于速度较慢的磁盘,延迟会更大。并行打开和读取多个文件比按顺序打开和读取要快得多,因为底层操作系统能够并行运行多个磁盘操作并优化磁盘访问。

在Python中创建不同的线程时,您可能需要确保获得单独的内核线程,而不是用户空间线程。您可以在传输期间检查每个CPU的利用率,以确保没有一个CPU饱和。正如其他地方建议的那样,您可能还需要检查两端存储子系统的利用率。

如果一次创建多个连接,还应该检查服务器系统,以确保没有溢出服务器侦听套接字的LISTEN队列。如果你有一个类似*nix的系统,你可以看看netstat-s的输出。

此外,除非这些是小文件,否则您可能会考虑接收大于4096字节的文件。

相关内容

  • 没有找到相关文章

最新更新