0

I've come to the realization where I need to change my design for a file synchronization program I am writing.

Currently, my program goes as follows:

1) client connects to server (and is verified)

2) if the client is verified, create a thread and begin a loop using the socket the client connected with

3) if a file on the client or server changes, send the change through that socket (using select for asynchronous communication)

My code sucks because I am torn between using one socket for file transfer or using a socket for each file transfer. Either case (in my opinion) will work, but for the first case I would have to create some sort of protocol to determine what bytes go where (some sort of header), and for the second case, I would have to create new sockets on a new thread (that do not need to be verified again), so that files can be sent on each thread without worrying about asynchronous transfer.

I would prefer to do the second option, so I'm investigating using SocketServer. Would this kind of problem be solved with SocketServer.ThreadingTCPServer and SocketServer.ThreadingMixIn? I'm having trouble thinking about it because I would assume SocketServer.ThreadingMixIn works for newly connected clients, unless I somehow have an "outer" socket server which servers "inner" socket servers?

Matt M
  • 149
  • 2
  • 4
  • 17

1 Answers1

0

SocketServer will work for you. You create one SocketServer per port you want to listen on. Your choice is whether you have one listener that handles the client/server connection plus per file connections (you'd need some sort of header to tell the difference) or two listeners that separate client/server connection and per file connections (you'd still need a header so that you knew which file was coming in).

Alternately, you could choose something like zeromq that provides a message transport for you.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • Can you elaborate on how i could do "two listeners that separate client/server connection and per file connections" with SocketServer? You basically restated my problem.. – Matt M Nov 10 '14 at 19:09
  • I need to pass the socket from one listener to another, essentially, right? – Matt M Nov 10 '14 at 19:14
  • Create two threads and have one create a threaded socket server for your "main" communications and the other to listen for file copies. – tdelaney Nov 10 '14 at 19:14
  • There are many ways to let the copy listener know what its supposed to do. Maybe the client sends a '\n' delimited string with the taget file name. Or, if you are concerned about security, the main listener could send an encrypted blob to the client and the client would send that back to the copy listener, right before the real data. – tdelaney Nov 10 '14 at 19:18
  • I only want to create a thread if the connection is verified by a correct user.. and then each time a file needs to be uploaded or downloaded, another thread is created. So can I have one SocketServer.ThreadingTCPServer create another SocketServer.ThreadingTCPServer with the same connection? – Matt M Nov 10 '14 at 19:32
  • Under the covers, ThreadingTCPServer does a socket listen on a tcp port and then it creates a new thread for each accept that comes in. Those would be the clients. A port can only have a single listener, so you can't just pass the server port to a new ThreadingTCPServer. You could pass in a different port number so that each file transfer happens on a different port, but that is highly unusual. If you are creating new connections for file transfers, you can't get around need to pass some sort of "magic cookie" around to make sure its only the authenticated user that can do the work. – tdelaney Nov 10 '14 at 19:42
  • So what would be my best option here to solve my problem then? Should I not use SocketServer? Should I check for authentication during each handle? – Matt M Nov 10 '14 at 19:48
  • SocketServer is fine. You authenticate clients and request that files be transferred, so you already have some sort of protocol. To send a file, the server could create a descriptor {'xferid':str(random.randint(0,100000000)), 'filename':'abc', 'status':'pending'}` and send xferid back to the client. The client could create a new connection and write `xferid + \x00 + data`. The server would look up xferid and know where to copy the file. A single SocketServer would tell the difference between a client connect and a data transfer by the first part of the message. – tdelaney Nov 10 '14 at 20:11