跨多个线程共享套接字变量

时间:2019-05-16 19:52:05

标签: python-3.x sockets connection

我似乎无法跨节点类中运行的多个线程共享从socket.accept()方法返回的conn,addr变量。我尝试使用队列,但是在打印列出队列内容时,它显示为空。

这是我收到conn,addr变量的地方。侦听器在节点类外部设置.run函数在node中调用join函数。

def run(node):
    successfulJoin=False
    print('Your ID in the IDSpace is:',node.getID())
    print('j to join node\n f to get node fingerTable\ns to show file\nd to download\nu to upload\nq to quit')
    cmd=input('choice:')
    if cmd=='j':
        print('joining node to',otherPort)
        successfulJoin=node.join(otherPort)


def listener(listsock,node,q):
 listsock.listen(7)
 print('Listening successfully on',port)
 stopAccept=False
 tup={}

 while not stopAccept:
    print('In listen looop')
    conn,addr=listsock.accept()
    tup['conn']=conn
    tup['addr']=addr
    print(type(conn))
    print('accepting connections,accepted conn:addr',(conn,addr))
    q.put(tup) 
    print('printing q contents in listener')
    print(list(q.queue)) #this does not get printed on consol for some reason?
    message=pickle.loads(conn.recv(4096*30))
    readRequest(message,conn,node)
    print('Received message, ,',message)
    print('Successfully accepted: ',listsock.getsockname(),'conn:',conn)
    reply=pickle.loads(conn.recv(4094))
    print('Received...',reply)
    if conn=='apply'and addr=='break':
            break
    if stopAccept:
            break
    listsock.close()

读取请求功能

def readRequest(request,conn,n):
    print('In readRequest') # does not printed on console??
    send=None
    if request == None:
        return None
    elif 'closestPrecedingFinger' in request:
        PID=request[0]
        print('in read Request,printing reques.split(',')i.e ID:',PID)
        reply=node.closestPrecedingFinger(ID)
        if reply !=None:
            port=reply[0]
            send=(port,"MYSUCCESSOR",None)
        else :
            send=(port,"EMPTY",None)
    elif 'YOURPRED' in request:
        reply=node.findPred()
        if reply !=None:
            port=request[0]
            reply=(port,"MYPRED",None)
        else:
            port=request[0]
            reply=(port,"EMPTY",None)
    elif 'Download' in request:
        p=request[0]
        r=request[1]
        filename=request[2]
    elif 'FINDSUCCESSOR' in request:
        PID=request[0]
        reply=node.findSuccessor(PID)
        send=(PID,'FOUNDSUCCESSOR',None)
    elif 'YOURSUCCESSOR'in request:
        PID=request[0]
        reply=node.getSucc()
        if reply !=None:
            send=(PID,'MYSUCCESSOR',None)
        else:
            send=(PID,'EMPTY',None)
    elif 'IAMPRED'in request:
        PID=request[0]
        node.setPred(PID)
        node.notified(PID)
        send(PID,'NOTIFIED',None)
    elif 'KEEP'in request:
        PID=request[0]
        send=(PID,'ALIVE',None)
    return send

想要在这些节点线程和节点类中的sendRequest函数之间共享

class node(object):   
 def __init__(self,port,joinPort,q):
  self.ip='localhost'
  self.threads['peer']=threading.Thread(target=makePeerList)     
  self.threads['stabilize']=threading.Thread(target=self.stabilize,args=(q,))          
  self.threads['fixFingers']=threading.Thread(target=self.fixFingers,args=(q,))
  self.threads['askPred']=threading.Thread(target=self.askPred,args=(q,))

加入功能

def join(self,destPort):
    print('starting join')
    if destPort!=None and destPort !=self.port: #if terminal args are different ports and a node currently exists
        self.startThreads(False)
        print('JOin destPort',destPort)
        print('getting address for succ')
        successor=self.getAddress(destPort,"FINDSUCCESSOR")
        if successor ==None:
            self.finger[0]=None
            print('Cannot find node you are tying to connect to..Leaving!')
            return False
        self.updateIthFinger(0,successor)
    self.startThreads(False) #else start threads for other nodes but does not join  
    return True

获取地址功能:

def getAddress(self,destPort,request):
    print('in get request')
    if destPort==None or request==None:
        return None
    # print('in get request')
    reply=self.sendRequest(self.q,destPort,request)
    if reply ==None:
        return None
    elif reply=="EMPTY":
        return destPort
    else:
        return reply

节点sendRequest函数

def sendRequest(self,q,destPort,request,filename=None): #listen conn shared here
    if destPort== None or request==None:
        return None
    print(' inSendrequest')
    reply=''
    print(list(q.queue),'THIS SHOWS EMPTY') #why is q empty?
    while q.empty !=True:
            conn=q.get()['conn']
    print('Sending tuple request...')
    conn.send(pickle.dumps((self.port,request,filename))) # this gives an error
    reply=pickle.loads(conn.recv(4096)) # gives error

    return reply

这是我运行侦听器线程并初始化q

的地方
def main():
  que=queue.Queue()
  n=node(port,otherPort,que)
  listsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  listsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  listsock.bind(('localhost',port))
  listenThread=threading.Thread(target=listener,args=[listsock,n,que])
  listenThread.setDaemon=True
  listenThread.start()
  run(n)
  print('Bound successfully')
  filenames=n.getFiles()
  n.sendRequest('FINDSUCCESSOR',otherPort,filenames[0])

运行python3 jode.py 4200 4200的最小输出日志。.运行第二个节点等的相同。python3 jode.py 5200 4200..get重复打印日志,因为线程继续运行,但是尽管放入了侦听器,但是队列仍然为空

  In listen looop
    joining node to 4200
    starting join
    in stabilize
    JOin destPort 4200
    getting address for succ
    in get request
     inSendrequest
    [] THIS SHOWS EMPTY
    in getSucc
    in updateFingers
    in fixFingers
    in ithStart
    Traceback (most recent call last):
  File "jode.py", line 660, in <module>
    main()
  File "jode.py", line 654, in main
    run(n)
  File "jode.py", line 41, in run
    successfulJoin=node.join(otherPort)
  File "jode.py", line 401, in join
    successor=self.getAddress(destPort,"FINDSUCCESSOR")
  File "jode.py", line 437, in getAddress
    reply=self.sendRequest(self.q,destPort,request)
  File "jode.py", line 637, in sendRequest
    conn=q.get(block=False)['conn']
  File "/usr/lib/python3.6/queue.py", line 161, in get
    raise Empty
queue.Empty

0 个答案:

没有答案