Hi,
I've been trying to code a simple file sharing system in python by using Discovery server -indexer- model

Server:

#!bin/python

import socket
import sys
import os
import threading
from utils import serialize, deserialize, PeerInfo


class NotSupportedCommand(Exception):
    pass



class DiscoveryServer(object):
    '''Indexer...'''
    def __init__(self, port, maxPeers=5):
        self.port=port
        addr=('', self.port)
        self.maxPeers=maxPeers
        self.supportedCommands=["/register", "/setNick", "/setSharedFiles", "/showall", "/query"]

        self.listener=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(addr)

        self.tListening=threading.Thread(target=self.listeningHandler, args=[])
        self.tListening.start()
        self.alSocks=[]
       # {clientAddr:peerInfo Object}
        self.db={}
        self.log=[]
        self.BUF=4096

    
    def listeningHandler(self):
        self.listener.listen(self.maxPeers)
        print "Server Started..."
        while True:
            clientSocket, clientAddr=self.listener.accept()
            print "Gotta a connection from", clientAddr
            tClientHandling=threading.Thread(target=self.clientHandler, args=[clientSocket])
            tClientHandling.start()
        clientSocket.close()

    def clientHandler(self, clientSocket):
       self.alSocks += [clientSocket]
       formatedAddress=clientSocket.getpeername()[0]+":"+str(clientSocket.getpeername()[1])
       objString=""
       try:
          while True:
                 objString=clientSocket.recv(self.BUF)
                 if not objString:
                        break
                 data=deserialize(objString)
                 #print data
                 tAnalyzeData=threading.Thread(target=self.analyzeData, args=[data, clientSocket])
                 tAnalyzeData.start()
                     
                 objString=""
                  
       except Exception, e:
           print "E: ", e 
           print clientSocket.getpeername(), " closed.."
           self.alSocks.remove(clientSocket)
           del self.db[formatedAddress]

                    
           
    def analyzeData(self, data, clientSocket):
       formatedAddress=clientSocket.getpeername()[0]+":"+str(clientSocket.getpeername()[1])
       try:
           if isinstance(data, tuple): #registering...
               pInfo=PeerInfo(data[1], data[2], data[3]) #(register, alias, files, port)
               print "Registering: ", pInfo.alias
               print pInfo
               self.db[formatedAddress]=pInfo #peerInfo object..
               print self.db

           if isinstance(data, list):
               try: 
                    #split the sender's alias..
                    #recvd=['tina: /showall']
                    recvd=data[0].split(": ")[1]
                    cmd=recvd.split(" ")[0]
                    # test cmd...
                    if not cmd in self.supportedCommands:
                        self.sendToAll(data, clientSocket) 
                    else:                     
                        if cmd=="/showall":
                            self.showAllTo(clientSocket)
                        if cmd=="/query":
                            fileName=recvd.split(" ")[1]
                            self.queryFile(fileName, clientSocket)
                        if cmd=="/setNick":
                            self.setNick(formatedAddress, recvd.split(" ")[1])
                                        
               except Exception,e :
                    print "Error: ", e
                    
                    
       except Exception, e:
                 print "Data: ", data
                 print "Error: ", e
                 self.alSocks.remove(clientSocket)
                
    def queryFile(self, fileName, clientSocket):
        print "Querying: ", fileName
        data=""
        for addr, pInfo in self.db.items():
            if fileName in pInfo.sharedFiles:
                data += "\n"+addr + " | " + pInfo.alias + " => " + fileName
                data += "\n\t" + pInfo.alias + " Listens at: "+ str(pInfo.listeningPort)        
        print data
        clientSocket.send(serialize(data))
        
    def showAllTo(self, clientSocket):
        
        data="\n---------------------------------------\nOnline Users:\n"
        for addr, pInfo in self.db.items():
            data += pInfo.alias + " -> " +addr +"\n"
        data +="\n----------------------------------------\n"
        print data
        clientSocket.send(serialize(data))
             
    def sendToAll(self, msg, clientEx):
        print "Message Recieved: ", msg
        try:
            for sock in self.alSocks:
                if not sock==clientEx:
                    sock.send(serialize(msg))
                else:
                    pass
        except Exception, e:
            print "Error: ", e

    def setNick(self, to, newNick):
        self.db[to].alias=newNick
        print "Nick Changed..."
        print self.db[to]
                                         

if __name__=="__main__":
    discoveryServer=DiscoveryServer(8080)

Peer

#!bin/python

import socket
import sys
import os
import threading
from utils import serialize, deserialize, PeerInfo
import random as rnd


    

class Peer(object):

    def __init__(self, alias, serverAddr=(), sharedFiles=[]):
     
        self.alias=alias
        self.serverAddr=serverAddr
        self.sharedFiles=sharedFiles
        self.tcpClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcpClient.connect(self.serverAddr)
        self.BUF=2048
        self.listeningPort=rnd.randint(8081, 10000)
        self.pInfo=PeerInfo(self.alias, self.sharedFiles, self.listeningPort) 

        self.addr=('', self.listeningPort) 
        print "\nConnected to server..."
        self.tClientToServer=threading.Thread(target=self.clientToServerHandler, args=[])
        self.tClientToServer.start()


        #listen for connections in background..
      
        self.listener=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(self.addr)

        self.tListening=threading.Thread(target=self.listeningHandler, args=[])
        self.tListening.start()

        
    def registerAtServer(self):
        msg=("/register", self.alias, self.sharedFiles, self.listeningPort)
        self.tcpClient.send(serialize(msg))

    
    def clientToServerHandler(self):

        print "Start Chatting.."
        #first register the files...
        self.registerAtServer()
        while True:
            tServerToClient=threading.Thread(target=self.serverToClientHandler, args=[])
            tServerToClient.start()
            data=raw_input()
            if not data:
                break
            if data.split(" ")[0]=="/fetch":
                addr, fileneeded=data.split(" ")[1:]
                tFetchFile=threading.Thread(target=self.fetchFile, args=[addr, fileneeded])
                tFetchFile.start()
            else:   
                msg=self.alias+": "+data
                self.tcpClient.send(serialize([msg]))

    def serverToClientHandler(self):
        while True:
            data=deserialize(self.tcpClient.recv(self.BUF))
            if not data: break

            if isinstance(data, list): #data ['tina: hi']
                print data[0]
            else:
                print data


    def fetchFile(self, addr, fileneeded):
        #addr is formated => addr:listeningPort
        endPoint=addr.split(":")[0], int(addr.split(":")[1])
        fetchTCPClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        fetchTCPClient.connect(endPoint)
        fetchTCPClient.send(serialize("/fetch", fileneeded, _from))
        tDownloadFile=threading.Thread(target=self.downloadFile, args=[fetchTCPClient, fileneeded])
        tDownloadFile.start()

    def downloadFile(self, fetchTCPClient, fileneeded):
        f=file(fileneeded, "wb")
        while True:
            dataRcvd=deserialize(fetchTCPClient.recv(self.BUF))
            if not dataRcvd: break
            f.write(dataRcvd)

    def listeningHandler(self):
        self.listener.listen(5)
        while True:
            clientSocket, clientAddr=self.listener.accept()
            tClientHandling=threading.Thread(target=self.clientHandler, args=[clientSocket])
            tClientHandling.start()
            
    def clientHandler(self, clientSocket):
        rcvd=clientSocket.recv(self.BUF)
        data=deserialize(rcvd)
        if isinstance(data, tuple):
            if data[0]=="/fetch": #go on..
                fileneeded=data[1] #(/fetch, fileneeded, _from)
                f=file(fileneeded, "rb")
                while True:
                    try:
                        clientSocket.send(serialize(f.read(self.BUF)))
                    except:
                        break
    
    
if __name__=="__main__":
    alias=raw_input("Alias: ")
    sharedFiles=os.listdir(os.getcwd())
    peer=Peer(alias, ('localhost', 8080), sharedFiles)

Utils module

import marshal
    
class PeerInfo(object):

    def __init__(self, alias, sharedFiles, listeningPort):
        self.alias=alias
        self.sharedFiles=sharedFiles
        self.listeningPort=listeningPort

    def __str__(self):
        sb="Alias: " + self.alias
        sb += "\nFiles: " + str(self.sharedFiles)
        sb +="\nListens At:" + str(self.listeningPort)
        return sb
    

def serialize(obj):
    '''Serialize an object to a string...'''

    return marshal.dumps(obj)

def deserialize(objString):
    '''Deserialize an object string...'''

    return marshal.loads(objString)  


if __name__=="__main__":
    p=PeerInfo("tina", [1, 2, 3 ,4], 80)
    print p
    print "alias: ",p.alias
    print "files: ", p.sharedFiles
    print "port : ", p.listeningPort

And it works (Querying, chating, changing nickS)
the only problem is when i try tofetch a file; it raises connection refused exception
any ideas ?

terribly sorry, peer.py totally sucks!
modified peer

#!bin/python

import socket
import sys
import os
import threading
from utils import serialize, deserialize, PeerInfo
import random as rnd


    

class Peer(object):

    def __init__(self, alias, serverAddr=(), sharedFiles=[]):
     
        self.alias=alias
        self.serverAddr=serverAddr
        self.sharedFiles=sharedFiles
        self.tcpClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcpClient.connect(self.serverAddr)
        self.BUF=1024
        self.listeningPort=rnd.randint(8081, 10000)
        self.pInfo=PeerInfo(self.alias, self.sharedFiles, self.listeningPort) 

        
        print "\nConnected to server..."
        self.tClientToServer=threading.Thread(target=self.clientToServerHandler, args=[])
        self.tClientToServer.start()


        #listen for connections in background..
        self.addr=('', self.listeningPort)
        self.listener=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(self.addr)

        self.tListening=threading.Thread(target=self.listeningHandler, args=[])
        self.tListening.start()

        
    def registerAtServer(self):
        msg=("/register", self.alias, self.sharedFiles, self.listeningPort)
        self.tcpClient.send(serialize(msg))

    
    def clientToServerHandler(self):

        print "Start Chatting.."
        #first register the files...
        self.registerAtServer()
        while True:
            tServerToClient=threading.Thread(target=self.serverToClientHandler, args=[])
            tServerToClient.start()
            data=raw_input()
            if not data:
                break
            if data.split(" ")[0]=="/fetch":
                fileneeded=data.split(" ")[1]
                addr=data.split(" ")[2]
                tFetchFile=threading.Thread(target=self.fetchFile, args=[addr, fileneeded])
                tFetchFile.start()
            else:   
                msg=self.alias+": "+data
                self.tcpClient.send(serialize([msg]))

    def serverToClientHandler(self):
        while True:
            data=deserialize(self.tcpClient.recv(self.BUF))
            if not data: break

            if isinstance(data, list): #data ['tina: hi']
                print data[0]
            else:
                print data


    def fetchFile(self, addr, fileneeded):
        #addr is formated => addr:listeningPort
        endPoint=addr.split(":")[0], int(addr.split(":")[1])
        fetchTCPClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        fetchTCPClient.connect(endPoint)
        fetchTCPClient.send(serialize(("/fetch", fileneeded)))
        tDownloadFile=threading.Thread(target=self.downloadFile, args=[fetchTCPClient, fileneeded])
        tDownloadFile.start()

    def downloadFile(self, fetchTCPClient, fileneeded):
       try:
           f=file(fileneeded, "wb")
           while True: 
                    dataRcvd=fetchTCPClient.recv(self.BUF)
                    if not dataRcvd: break
                    f.write(dataRcvd)
           f.close()
           print "File Downloaded!"
           
       except:
           print "Error: ", e

        


    def listeningHandler(self):
        self.listener.listen(5)
        while True:
            clientSocket, clientAddr=self.listener.accept()
            tClientHandling=threading.Thread(target=self.clientHandler, args=[clientSocket])
            tClientHandling.start()
            
    def clientHandler(self, clientSocket):
        rcvd=clientSocket.recv(self.BUF)
        data=deserialize(rcvd)
        if isinstance(data, tuple):
            if data[0]=="/fetch": #go on..
                fileneeded=data[1] #(/fetch, fileneeded, from)
                print "File Request: ", fileneeded
                f=file(fileneeded, "rb")
                while True:
                    try:
                        clientSocket.send(f.read(self.BUF))
                    except:
                        break
    
    
if __name__=="__main__":
    alias=raw_input("Alias: ")
    sharedFiles=os.listdir(os.getcwd())
    peer=Peer(alias, ('localhost', 8080), sharedFiles)

NOW it works but it doesn't reach this block

f.close()
           print "File Downloaded!"

Fixed:

#!bin/python

import socket
import sys
import os
import threading
from utils import serialize, deserialize, PeerInfo
import random as rnd


    

class Peer(object):

    def __init__(self, alias, serverAddr=(), sharedFiles=[]):
     
        self.alias=alias
        self.serverAddr=serverAddr
        self.sharedFiles=sharedFiles
        self.tcpClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcpClient.connect(self.serverAddr)
        self.BUF=4096
        self.listeningPort=rnd.randint(8081, 10000)
        self.pInfo=PeerInfo(self.alias, self.sharedFiles, self.listeningPort) 

        
        print "\nConnected to server..."
        self.tClientToServer=threading.Thread(target=self.clientToServerHandler, args=[])
        self.tClientToServer.start()


        #listen for connections in background..
        self.addr=('', self.listeningPort)
        self.listener=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(self.addr)

        self.tListening=threading.Thread(target=self.listeningHandler, args=[])
        self.tListening.start()

        
    def registerAtServer(self):
        msg=("/register", self.alias, self.sharedFiles, self.listeningPort)
        self.tcpClient.send(serialize(msg))

    
    def clientToServerHandler(self):

        print "Start Chatting.."
        #first register the files...
        self.registerAtServer()
        while True:
            tServerToClient=threading.Thread(target=self.serverToClientHandler, args=[])
            tServerToClient.start()
            data=raw_input()
            if not data: continue
            if data.lower=="exit": exit()
            
            if data.split(" ")[0]=="/fetch":
                fileneeded=data.split(" ")[1]
                addr=data.split(" ")[2]
                tFetchFile=threading.Thread(target=self.fetchFile, args=[addr, fileneeded])
                tFetchFile.start()
            else:   
                msg=self.alias+": "+data
                self.tcpClient.send(serialize([msg]))

    def serverToClientHandler(self):
        while True:
            data=deserialize(self.tcpClient.recv(self.BUF))
            if not data: break

            if isinstance(data, list): #data ['tina: hi']
                print data[0]
            else:
                print data


    def fetchFile(self, addr, fileneeded):
        #addr is formated => addr:listeningPort
        endPoint=addr.split(":")[0], int(addr.split(":")[1])
        fetchTCPClient=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        fetchTCPClient.connect(endPoint)
        fetchTCPClient.send(serialize(("/fetch", fileneeded)))
        tDownloadFile=threading.Thread(target=self.downloadFile, args=[fetchTCPClient, fileneeded])
        tDownloadFile.start()

    def downloadFile(self, fetchTCPClient, fileneeded):
##       try:
##           f=file(fileneeded, "wb")
##           while True: 
##                    dataRcvd=fetchTCPClient.recv(self.BUF)
##                    if not dataRcvd: break
##                    f.write(dataRcvd)
##
##           print "File Downloaded!" 
##
##       except Exception, e:
##           print "Error: ", e
##           
##       finally:
##           print "Closing the file.."
##           fetchTCPClient.close()
##           f.close()
        f=file(fileneeded, "wb")
        while True:
            try:
                buf=fetchTCPClient.recv(self.BUF)
                if not buf:
                    break
                f.write(buf)
            except EOFError, eofErr:
                print "EOFError: ", eofErr
            except Exception, e:
                print "Error: ", e
                break
        print "File Downloaded!"
        f.close()
        fetchTCPClient.close()

            
        


    def listeningHandler(self):
        self.listener.listen(5)
        while True:
            clientSocket, clientAddr=self.listener.accept()
            tClientHandling=threading.Thread(target=self.clientHandler, args=[clientSocket])
            tClientHandling.start()
            
    def clientHandler(self, clientSocket):
        rcvd=clientSocket.recv(self.BUF)
        data=deserialize(rcvd)
        if isinstance(data, tuple):
            if data[0]=="/fetch": #go on..
                fileneeded=data[1] #(/fetch, fileneeded, from)
                print "File Request: ", fileneeded
                f=file(fileneeded, "rb")
                while True:
                    try:
                        buf=f.read(self.BUF)
                        if not buf:
                            break
                        clientSocket.send(buf)
                    except Exception, e:
                        print "Error: ", e
                        break
               
                f.close()
                clientSocket.close()
                print "Copied!"
                        
    
    
if __name__=="__main__":
    alias=raw_input("Alias: ")
    sharedFiles=os.listdir(os.getcwd())
    peer=Peer(alias, ('localhost', 8080), sharedFiles)

Thanks & Sorry

This article has been dead for over six months. Start a new discussion instead.