1

I am trying multiple clients to send files to the server simultaneously on one port(i.e. server is running different ports and multiple clients are connected to each port and sending files). I have looked several answers such as this, but they are using different approaches and I just want somebody to pinpoint what I am doing wrong here, so I can use same code which I understand better. Please help me with:

  1. Why my code is not working with multiple file transfer?
  2. I am also calculating the throughput(i.e. actual file transfer), is it the correct method?

Thanks for help.

 ----- 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 side

----- 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!"


Tabz
  • 137
  • 1
  • 11

2 Answers2

0

There is at least one problem: the recfile file is opened before starting the loop, and closed inside the loop. That means that beginning from the second iteration, you will try to write on a closed file and get an exception.

How to avoid: with open(...) as ...: blocks are great because not only they guarantee proper closure in case of errors, but they also ensure a correct bloc structure in your program.

BTW, count should also be reset to 0 inside the loop, and the closer to the loop the better for future readers and maintainers of the code

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks, I have moved the file creation to the `while` loop, and now files are creating but still one-by-one – Tabz Jul 30 '20 at 09:29
  • @Tabz: Then try to leave to file creation before the loop and move the close after it. Or better use a `with`: `with open() as f while 1: ...` – Serge Ballesta Jul 30 '20 at 09:43
  • using `with open()`helped to complete file transfer but taking it out of `while loop` is creating one file per connection only, so It should be inside so creates one data file per connection. do you think i should `multiprocessing` ? – Tabz Jul 30 '20 at 11:36
  • I would not use multiprocessing for a IO bound question but just multithreading or simply `select`. You could find [here](https://stackoverflow.com/q/17453212/3545273) an example of the threading module. – Serge Ballesta Jul 30 '20 at 12:10
  • Thanks both, I found a solution with `multiprocessing` posting now.. – Tabz Jul 30 '20 at 15:05
0

I found a solution by improvising this . Multiple connection to same socket is not possible without either multiprocessing or multithreading. Since I am using Python 2.7 multithreading is not an option for me.

Tabz
  • 137
  • 1
  • 11
  • *Multiple connection to same socket is not possible without either multiprocessing or multithreading*. I am sorry but this is plain wrong. Since the existence of `select` (from unix BSD 4), it was possible to write multi client servers without threads. And as Python offers a `select` interface on sockets... – Serge Ballesta Jul 30 '20 at 15:16