class ServerForCs(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.port = SERVER_PORT self.host = SERVER_HOST self.users = set() self.userinfos = {} self.sockets = set() self.msg = Message() self.running = 1 self.lock = threading.Lock() self.threads = {} #主线程对每个用户开启一个接受消息的监听线程 def run(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) s.bind(ADDR) s.listen(1) while self.running == True: clientsock, addr = s.accept() self.sockets.add(clientsock) print "accept msf from ", addr #when recieve a socket create a new thread t = threading.Thread(target=self.recv, args=[clientsock]) #add beat thread for each clientsocket here #t2 = threading.Thread(target=self.recvBeat, args=[clientsock]) self.threads[clientsock] = t #self.handshaked[clientsock] = [False,t2] #t2.start() t.start() #t2.start() #服务器给一个用户发送消息 def sendMessageToAClient(self, clientsock, types, data= None): msg = '' if types == "handshake": msg = self.msg.handshakeMsg(self.host) if types == "loginJudge": status = data[0] reason = data[1] msg = self.msg.loginServerMsg(status, reason) if types == "onlineUserList": msg = self.msg.getOnlineUserListMsg(data) print 'Send for heartbeat response' if types == "dialogReturn": username = data[0] dialog = data[1] msg = self.msg.serverSendToUserMsg(username, dialog) if msg != '': clientsock.send(msg) #Thread.exit_thread() #检查在线用户 def checkAliveUsers(self, client_host, client_port): pass #给所有用户发送聊天信息 def sendMessageToAllClient(self, username, msg): #print self.threads for clientsock in self.threads.keys(): self.sendMessageToAClient(clientsock, "dialogReturn", [username, msg]) thread.exit_thread() #清理用户消息 def removeAliveClient(self, clientsock): client_host, client_port = clientsock.getpeername() if self.threads.has_key(clientsock): self.lock.acquire() del self.threads[clientsock] username = self.userinfos[(client_host, client_port)] self.users.remove(username) del self.userinfos[(client_host, client_port)] self.lock.release() thread.exit_thread() #将接收到的信息根据协议分类 def recvHandshake(self, clientsock): #print 'Here' self.sendMessageToAClient(clientsock, "handshake") thread.exit_thread() def recvLogin(self, clientsock, lines): print 'LOGIN DEAL' #print "lines:", lines client_host, client_port = clientsock.getpeername() requestline = lines[0].split(' ') username = requestline[2] port = int((lines[1].split(' '))[1]) #print username, port name_exsit = False status = '1' reason = 'success' #print self.userinfos if username in self.users: name_exsit = True else: #print 'Process users infos' self.lock.acquire() self.users.add(username) self.userinfos[(client_host, port)] = username self.lock.release() print 'Processed' if name_exsit == True: status = '0' reason = 'username already exist' print status, reason print 'Status' self.sendMessageToAClient(clientsock, "loginJudge", [status, reason]) thread.exit_thread() def recvGetlist(self, clientsock): userinfos = {} userinfos = {} for ips in self.userinfos.keys(): user = self.userinfos[ips] userinfos[user] = ips self.sendMessageToAClient(clientsock, "onlineUserList",userinfos) thread.exit_thread() def recvLeave(self, clientsock): client_host, client_port = clientsock.getpeername() if (client_host, client_port) in self.userinfos.keys(): self.lock.acquire() name = self.userinfos[(client_host, client_port)] del self.userinfos[(client_host, client_port)] self.users.remove(name) self.lock.release() else: print 'Error user!' thread.exit_thread() def recvMessage(self, clientsock, lines): #lines = clientsock.recv(BUFSIZ).split('\n') requestline = lines[0].split(' ') msg = lines[3] #print msg username = requestline[2] #time = (lines[1].split('HEADERNAME '))[1] self.sendMessageToAllClient(username, msg) thread.exit_thread() def recvBeat(self, clientsock): #first time then send return message for getting the list client_host, client_port = clientsock.getpeername() userinfos = {} for ips in self.userinfos.keys(): user = self.userinfos[ips] userinfos[user] = ips self.sendMessageToAClient(clientsock, "onlineUserList", userinfos) thread.exit_thread() #self.checkAliveUsers(client_host, client_port)userinfos = {} #对每一个用户进行监听的接收函数,通过判断发送的协议类型调用不同的处理函数 def recv(self, clientsock): while True: client_host, client_port = clientsock.getpeername() msg = clientsock.recv(BUFSIZ) lines = msg.split('\n') requestline = lines[0].split(' ') # print lines[0] #print 'test' + repr(requestline) if 'MINET' in requestline: print 'Yes' else : print 'No' if msg != '': print 'Received message from ', client_host, client_port #judge type if 'MINET' in requestline: print 'GOT HANDSHAKE' t = threading.Thread(target=self.recvHandshake, args=[clientsock]) t.start() if 'LOGIN' in requestline: print 'GOT LOGIN' t = threading.Thread(target=self.recvLogin, args=[clientsock, lines]) t.start() if 'GETLIST' in requestline: t = threading.Thread(target=self.recvGetlist, args=[clientsock]) t.start() if 'BEAT' in requestline: t = threading.Thread(target=self.recvBeat, args=[clientsock]) t.start() if 'MESSAGE' in requestline: t = threading.Thread(target=self.recvMessage, args=[clientsock, lines]) t.start() if 'LEAVE' in requestline: t = threading.Thread(target=self.recvLeave, args=[clientsock]) t.start() thread.exit_thread() else: t = threading.Thread(target=self.recvLeave, args=[clientsock]) t.start() thread.exit_thread() def kill(self): self.running = 0
def createClient(clientsock,client): global cancelSignal global judge global usernames global userips global login global p2p global time_beat m = Message() name = "" while True: try: reco = clientsock.recv(1024) print "close1" except socket.error, (value, message): print "close2" clientsock.close() if judge[name] == 0: print "close3" break pass rec_all = reco.split('\n') rec = rec_all[0].split(' ') for x in rec: print x pass if rec[0] != "CS1.1": #print "break" break pass if rec[1] == 'LOGIN': #用户登录 if rec[2] in usernames: clientsock.send(m.loginServerMsg("0","有相同用户名用户")) #print m.loginServerMsg("0","有相同用户名用户") continue pass else: if client[0] in userips: clientsock.send(m.loginServerMsg('0',"之前已登录")) #print m.loginServerMsg('0',"之前已登录") continue pass else: name = rec[2] clientsock.send(m.loginServerMsg('1',"")) #print m.loginServerMsg('1',"") mutex.acquire() usernames.add(rec[2]) userips.add(client[0]) login[rec[2]] = client p = rec_all[1].split(' ') p2p[rec[2]] = [str(client[0]),p[1]] time_beat[rec[2]] = getTime() thread.start_new_thread(sendMessageToAll, (clientsock,client,rec[2])) thread.start_new_thread(Beat, (rec[2],clientsock)) time.sleep(0.05) cancelSignal = rec[2] judge[rec[2]] = 1#1为上线,0为下线 mutex.release() eve.set() pass if rec[1] == 'GETLIST': clientsock.send(m.getOnlineUserListMsg(login)) #print m.getOnlineUserListMsg(login) pass if rec[1] == 'LEAVE': #群聊监听用户发来信息 if rec[2] in usernames: #如果下线用户还在用户列表中,说明他是第一次下线,因为有可能是从心跳中剔除了名字 usernames.remove(rec[2])#移除名字 userips.remove(login[rec[2][0]])#移除Ip地址 del login[rec[2]] judge[rec[2]] = 0 #1为上线,0为下线 #mutex.release() #终结该用户的群聊线程 mutex.acquire() cancelSignal = count mutex.release() clientsock.close() eve.set() break pass pass if rec[1] == 'MESSAGE': global messageAll mutex.acquire() messageAll = m.serverSendToUserMsg(rec[2],rec_all[3]) mutex.release() eve.set() pass if rec[1] == 'P2PCONNECT': clientsock.send(m.ServerP2p(rec[2],p2p[rec[2]][0],p2p[rec[2]][1])) pass if rec[1] == 'BEAT': print "rec[2]",rec[2] time_lock.acquire() time_beat[rec[2]] = getTime() time_lock.release() pass