Reputation: 173
I have a question about some Python socket programming. I'm pretty new to sockets and probably just have a poor understanding of how they work. I need to transfer a binary file between two machines while running a python application and figured doing some socket programming would be better/faster than doing a system command scp or netcat. For some reason though, if I transfer a 1GB image between my machines it takes ~14 seconds. If I do it via SCP it only takes about 9. This seems odd since SCP is notoriously slow. I was hoping my transfer speeds would be comparable to netcat but I'm having trouble achieving this.
Server:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 50000))
s.listen(1)
img = open('test.img', 'rb')
client, addr = s.accept()
l = img.read(4096)
while(l):
client.send(l)
l = img.read(4096)
img.close()
s.close()
Client:
host = ''
port = 50000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
img = open('./newimg.img', 'wb')
l = s.recv(4096)
while(l):
img.write(l)
l = s.recv(4096)
img.close()
s.close()
This is obviously extremely basic and lacks a lot of features and exception handling but it at least gets a file to transfer (slowly though). I've obviously removed a few details from my code like the 'host' variable.
How can I improve this?
Thanks!
Upvotes: 4
Views: 8870
Reputation: 1167
I would suggest increasing the size of the buffer from 4096 to a larger size. This would reduce the number of times items would be going through stack operations and interpretations of Python, which may increase the speed at which the data is transferred.
Currently, at 4096 (4K) byte read, you will be making 262144 read/write from socket for a one gigabyte file. If you could increase the buffer to be one 1048576 bytes (1024K), then there would only be 1024 read/writes from socket and file for a one gigabyte file. That would let the optimized code of the system call do more of the efforts. Since I don't know how much RAM memory might be available it might help to make it as big as feasibly possible but leaving some memory free for a bit of margin.
For an example, in one system I worked with, we sent over small quantities of data and could not get the performance we expected. We queued up a bunch of the small quantities of data in one larger message and was able to get the performance which we required. From best we could determine we were spending a lot of time calling system function which going back and forth through the stack for small amounts was part of the issue.
However, it may be that scp could still be possibly be faster as it is compiled machine code and does not have the interpretation to go through even if it has additional overhead.
Upvotes: 4
Reputation:
Make the buffer size of s.recv() larger so it receives more bytes at a time
Upvotes: 0