我似乎无法跨节点类中运行的多个线程共享从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