== 원본 == {{{~cpp import socket from SocketServer import ThreadingTCPServer, StreamRequestHandler import thread PORT = 8037 lock = thread.allocate_lock() # 상호 배제 구현을 위한 락 객체 class UsersList: def __init__(self): self.users = {} def __contains__(self, name): # in 연산자 메쏘드 return name in self.users def addUser(self, conn, addr, name): if name in self.users: conn.send('Already resistered name\n') return None lock.acquire() # 상호 배제 self.users[name] = (conn, addr) lock.release() # 각종 메시지 출력 self.broadcastMessage('['+name+']' + ' entered\n') conn.send('[%s] Welcome!\n'%name) # 본인에게 가는 메시지 print len(self.users), 'connections' # 서버에 표시되는 메시지 return name def removeUser(self, name): if name not in self.users: return lock.acquire() # 상호 배제 del self.users[name] lock.release() self.broadcastMessage('['+name+'] '+' has gone!\n') print len(self.users), 'connections' # 서버에 표시되는 메시지 def handleMessage(self, name, msg): if msg[0] != '/': self.broadcastMessage('['+name+'] ' + msg) return cmd = msg[1:].rstrip().split() if cmd[0] == 'quit': self.removeUser(name) return -1 def broadcastMessage(self, msg): for conn, addr in self.users.values(): conn.send(msg) class RequestHandler(StreamRequestHandler): users = UsersList() # 접속 요구가 들어오면 호출된다. def handle(self): print 'connection from', self.client_address #서버에 표시되는 메시지 conn = self.request try: name = self.readAngRegisterName() data = self.receiveline() while data: if self.users.handleMessage(name, data) == -1: conn.close() break data = self.receiveline() except socket.error: print 'Socket Error' print 'Disconnected from', self.client_address #서버 메시지 self.users.removeUser(name) #참여자 이름을 읽어서 등록한다 def readAngRegisterName(self): while 1: self.request.send('Name ? ') name = self.receiveline().strip() #이름 읽기 if self.users.addUser(self.request, self.client_address, name): return name #한 라인을 읽어들인다. def receiveline(self): line = [] while 1: data = self.request.recv(1024) line.append(data) if data[-1] == '\n': return ''.join(line) # ============================================================ if __name__ == '__main__': server = ThreadingTCPServer(("", PORT), RequestHandler) print 'listening on port', PORT server.serve_forever() }}} == 수정 == {{{~cpp import socket from SocketServer import ThreadingTCPServer, StreamRequestHandler import thread PORT = 4444 lock = thread.allocate_lock() # 상호 배제 구현을 위한 락 객체 class Users: def __init__(self, aId, msg,addr, isinEntry = False): self.ID = aID self.message = msg ## self.conn = conn self.addr = addr self.isinEntry # def __contains__(self, name): # in 연산자 메쏘드 # return name in self.users def addUser(self): if self.isinEntry: self.send('Already resistered name\n') return None lock.acquire() # 상호 배제 self.append(Users(self.ID, self.message, self.isinEntry)) lock.release() # 각종 메시지 출력 self.broadcastMessage('['+self.ID+']' + ' entered\n') self.send('[%s] Welcome!\n'%self.ID) # 본인에게 가는 메시지 print len(Users), 'connections' # 서버에 표시되는 메시지 return self.ID def removeUser(self): if self.ID not in Users: return lock.acquire() # 상호 배제 self.remove(Users) lock.release() self.broadcastMessage('['+self.ID+'] '+' has gone!\n') print len(Users), 'connections' # 서버에 표시되는 메시지 def handleMessage(self, msg): if msg[0] != '/': self.broadcastMessage('['+self.ID+'] ' + msg) return cmd = msg[1:].rstrip().split() # if cmd[0] == 'quit': # self.removeUser(name) # return -1 # self.users[name] = (conn, addr) # def broadcastMessage(self, msg): # for conn, addr in Users: # conn.send(msg) class RequestHandler(StreamRequestHandler): # 접속 요구가 들어오면 호출된다. def handle(self): print 'connection from', self.client_address # client address #서버에 표시되는 메시지 conn = self.request # conn : object a = conn.recv(1024) u = Users(a.ID, a.message,self.client_address, a.isinEntry) u.addUser() conn.send(u.ID) try: ## name = self.readAngRegisterName() data = self.receiveline() while data: if self.users.handleMessage(data) == -1: conn.close() break data = self.receiveline() except socket.error: print 'Socket Error' print 'Disconnected from', self.client_address #서버 메시지 u.remove(u) #참여자 이름을 읽어서 등록한다 ## def readAngRegisterName(self): ## while 1: ## self.request.send('Name ? ') ## name = self.receiveline().strip() #이름 읽기 ## if self.users.addUser(self.request, self.client_address, name): ## return name #한 라인을 읽어들인다. def receiveline(self): line = [] while 1: data = self.request.recv(1024) line.append(data) if data[-1] == '\n': return ''.join(line) # ============================================================ if __name__ == '__main__': server = ThreadingTCPServer(("", PORT), RequestHandler) print 'listening on port', PORT server.serve_forever() }}} == 재선 == {{{~cpp import socket from SocketServer import ThreadingTCPServer, StreamRequestHandler import thread PORT = 8037 lock = thread.allocate_lock() # 상호 배제 구현을 위한 락 객체 class UsersList: def __init__(self): self.users = {} def __contains__(self, name): # in 연산자 메쏘드 return name in self.users def addUser(self, conn, msg, name): if name in self.users: conn.send('Already resistered name\n') return None lock.acquire() # 상호 배제 self.users[name] = (conn, msg) lock.release() # 각종 메시지 출력 self.broadcastMessage('['+name+']' + ' entered\n') conn.send('[%s] Welcome!\n'%name) # 본인에게 가는 메시지 print len(self.users), 'connections' # 서버에 표시되는 메시지 return name #('id' : (object, message)) def removeUser(self, name): if name not in self.users: return lock.acquire() # 상호 배제 del self.users[name] lock.release() self.broadcastMessage('['+name+'] '+' has gone!\n') print len(self.users), 'connections' # 서버에 표시되는 메시지 def handleMessage(self, name, msg): if msg[0] != '/': self.broadcastMessage('['+name+'] ' + msg) return cmd = msg[1:].rstrip().split() if cmd[0] == 'quit': self.removeUser(name) return -1 def broadcastMessage(self, msg): for conn, addr in self.users.values(): conn.send(msg) class RequestHandler(StreamRequestHandler): users = UsersList() # 접속 요구가 들어오면 호출된다. def handle(self): print 'connection from', self.client_address #서버에 표시되는 메시지 conn = self.request try: name = self.users.addUser(self.request, self.client_address, name) if name: conn.send(true) else: conn.send(false) data = self.receiveline() while data: if self.users.handleMessage(name, data) == -1: conn.close() break data = self.receiveline() except socket.error: print 'Socket Error' print 'Disconnected from', self.client_address #서버 메시지 self.users.removeUser(name) #참여자 이름을 읽어서 등록한다 ## def readAngRegisterName(self): ## while 1: ## self.request.send('Name ? ') ## name = self.receiveline().strip() #이름 읽기 ## if self.users.addUser(self.request, self.client_address, name): ## return name #한 라인을 읽어들인다. def receiveline(self): line = [] while 1: data = self.request.recv(1024) line.append(data) if data[-1] == '\n': return ''.join(line) # ============================================================ if __name__ == '__main__': server = ThreadingTCPServer(("", PORT), RequestHandler) print 'listening on port', PORT server.serve_forever() }}} {{{~cpp import tkSimpleDialog from Tkinter import * from socket import * class Main: def __init__(self, aMaster, aUser, aSock): self.frame = Frame(aMaster) #for show texts self.showscrollbar = Scrollbar(aMaster) self.showscrollbar.place(x = 550, y = 0, width = 50, height = 550) self.show = Listbox(aMaster, yscrollcommand = self.showscrollbar.set) self.show.place(x = 0, y = 0, width = 585, height = 550) self.showscrollbar.config(command = self.show.yview) #for user list self.listscrollbar = Scrollbar(aMaster) self.listscrollbar.place(x = 800-50, y = 0, width = 50, height = 600) self.list = Listbox(aMaster, yscrollcommand = self.listscrollbar.set) self.list.place(x = 600, y = 0, width = 185, height = 600) self.listscrollbar.config(command = self.list.yview) #for input a string self.edit = Entry(aMaster) self.edit.place(x = 0, y = 550 , width = 600 , height = 50) def sendMessage(self, event): aUser.message = self.edit.get() self.edit.delete(0, END) csock.send(aUser) self.recieveMassage() def recieveMassage(self): user = aSock.recv(1024) self.show(user) def show(self, aUser): self.show.insert(END, "< " + str(aUser.ID) + " > : " + str(aUser.message)) class User: def __init__(self, aID): self.ID = aID self.message = '' ## self.isinEntry = True if __name__ == "__main__": root = Tk() root.configure( width = 800, height = 600) login = tkSimpleDialog ## login.Place.place_configure( root, x = 100, y = 100) #position csock = socket(AF_INET, SOCK_STREAM) try: csock.connect(('', 8037))#make socket, connect except: print 'connect refuse' ## csock.recv(1024) ID = '' while not ID: ID = login.askstring(title = "Login", prompt="Enter ID", parent = root) user = User(ID) csock.send(user.ID) registered= csock.recv(1024) if registered: continue else: win = Main(root, user, csock) root.bind("", win.sendMessage) while True: user = csock.recv(1024) root.mainloop() }}} ---- [2학기파이선스터디]