소켓 랜덤채팅 본문
Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | # -*- coding:utf-8 -*- # socket 과 select 모듈 임포트 from socket import * from select import * import sys, thread, threading from time import ctime from collections import deque class UserInfo(): def __init__(self): self.name_list = [] self.socket_dic = {} self.addr_dic = {} def addInfo(self, name, socket, ADDR): self.name_list.append(name) self.socket_dic[name] = socket self.addr_dic[name] = ADDR def getSocket(self, name): return self.socket_dic[name] def getAddr(self, name): return self.addr_dic[name] def remove(self, name): self.name_list.remove(name) del self.socket_dic[name] del self.addr_dic[name] class ChatRoom(threading.Thread): # Thread 객체 상속, ChatRoom 클래스 정의 def __init__(self, n, c1, c2, userinfo, cnames): threading.Thread.__init__(self) self.room_number = n self.userinfo = userinfo self.cnames = cnames self.connection_list = [c1, c2] def run(self): # run 메소드 정의 while len(self.connection_list)==2: read_socket, write_socket, error_socket = select(self.connection_list, [], [], 10) for sock in read_socket: from_name = 'Unknown' for cname in self.cnames: if userinfo.getSocket(cname) == sock: from_name = cname data = sock.recv(BUFSIZE) print(data) if data == 'quit': self.connection_list.remove(sock) self.cnames.remove(from_name) userinfo.remove(from_name) sock.close() sock = None waiting_queue.append(self.cnames[0]) userinfo.getSocket(self.cnames[0]).send('[INFO] 상대가 대화방을 나갔습니다. 새로운 상대를 기다립니다.') print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), from_name)) break elif data: print('[INFO][%d][%s] %s 클라이언트로부터 데이터를 전달 받았습니다.' %(self.room_number, from_name, ctime())) for cname in cnames: if userinfo.getSocket(cname) != sock: socket_in_list = userinfo.getSocket(cname) try: socket_in_list.send('<%s (상대)> %s [%20s]' % (from_name, data, ctime())) print('[INFO][%d][%s] 클라이언트로 데이터를 전달합니다.' %(self.room_number, ctime())) except Exception as e: print(e.message) socket_in_list.close() self.connection_list.remove(socket_in_list) cnames.remove(cname) continue else: self.connection_list.remove(sock) if userinfo.getSocket(cnames[0]) == sock: cnames.remove(cnames[0]) sock.close() sock = None print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), cnames[0])) else: cnames.remove(cnames[1]) sock.close() sock = None print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), cnames[1])) print(room_threads) print('[INFO] %d chatroom thread done!!' %self.room_number) del room_threads[self.room_number] print(room_threads) def handler(sysin): # exit 입력을 처리할 핸들러 while 1: message = sysin.readline() if(message == "exit\n"): try: for th in room_threads: th.join() connection_list.pop() sys.exit() except SystemExit: print("SERVER EXIT") except: print("Something went horribly wrong") # 호스트, 포트와 버퍼 사이즈를 지정 HOST = '' PORT = 1614 BUFSIZE = 1024 ADDR = (HOST, PORT) room_i = 0 # 소켓 객체를 만들고.. serverSocket = socket(AF_INET, SOCK_STREAM) # 서버 정보를 바인딩 serverSocket.bind(ADDR) # 요청을 기다림(listen) serverSocket.listen(10) connection_list = [serverSocket] waiting_queue = deque() room_threads = {} userinfo = UserInfo() print('==============================================') print('채팅 서버를 시작합니다. %s 포트로 접속을 기다립니다.' % str(PORT)) print('==============================================') in_thread = thread.start_new_thread(handler, (sys.stdin, )) # 무한 루프를 시작` while connection_list: try: print('[INFO] 요청을 기다립니다...') # select 로 요청을 받고, 10초마다 블럭킹을 해제하도록 함 read_socket, write_socket, error_socket = select(connection_list, [], [], 10) for sock in read_socket: # 새로운 접속 if sock == serverSocket: clientSocket, addr_info = serverSocket.accept() #connection_list.append(clientSocket) print('[INFO][%s] 클라이언트(%s)가 새롭게 연결 되었습니다.' % (ctime(), addr_info[0])) name = clientSocket.recv(20) userinfo.addInfo(name, clientSocket, addr_info) if (len(waiting_queue) < 1): waiting_queue.append(name) print(waiting_queue) print('[INFO] 대화상대를 찾고있습니다.') clientSocket.send('[INFO] 대화상대를 찾고있습니다.') else: waiting_queue.append(name) print('[INFO] 대화상대를 찾고있습니다.') clientSocket.send('[INFO] 대화상대를 찾고있습니다.\n') clients = [] cnames = [] for wname in waiting_queue: if (len(clients) <= 1): clients.append([userinfo.getSocket(wname), userinfo.getAddr(wname)]) cnames.append(wname) try: room_i += 1 clients[0][0].send('[%s] %s님과 %s님의 대화방입니다.' %(ctime(), cnames[0], cnames[1])) clients[1][0].send('[%s] %s님과 %s님의 대화방입니다.' %(ctime(), cnames[1], cnames[0])) chatroom = ChatRoom(room_i, clients[0][0], clients[1][0], userinfo, cnames) chatroom.start() room_threads[room_i] = chatroom waiting_queue.clear() except Exception as e: clients[0][0].close() clients[1][0].close() waiting_queue.clear() except KeyboardInterrupt: # 부드럽게 종료하기 serverSocket.close() sys.exit() | cs |
Client
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # -*- coding:utf-8 -*- # socket 모듈을 임포트 from socket import * from select import select import sys, thread, time # 호스트, 포트와 버퍼 사이즈를 지정 HOST = '' PORT = 1614 BUFSIZE = 1024 ADDR = (HOST, PORT) name = 'Unknown' recv_check=0 def handler(): while 1: message = raw_input() if(message == ""): prompt() message = raw_input() if(message == "quit"): try: clientSocket.send('quit') clientSocket.close() sys.exit() except SystemExit: print("프로그램을 종료합니다.") except: print("Something went horribly wrong") clientSocket.send(message) def prompt(): sys.stdout.write('<'+name+ '(나)> ') sys.stdout.flush() # 소켓 객체를 만들고 clientSocket = socket(AF_INET, SOCK_STREAM) # 서버와의 연결을 시도 try: clientSocket.connect(ADDR) except Exception as e: print('채팅 서버에 연결 할 수 없습니다.') sys.exit() print('채팅 서버에 연결 되었습니다.') name = raw_input('닉네임을 입력하세요 : ') clientSocket.send(name) in_thread = thread.start_new_thread(handler, ( )) # 무한 루프를 시작 while True: try: recv_check=0 connection_list = [clientSocket] read_socket, write_socket, error_socket = select(connection_list, [], [], 10) for sock in read_socket: if sock == clientSocket: data = sock.recv(BUFSIZE) recv_check = 1 if not data: print('채팅 서버와의 연결이 끊어졌습니다.') clientSocket.close() sys.exit() else: print('%s' % data) # 메세지 시간은 서버 시간을 따른다 if(data != '[INFO] 대화상대를 찾고있습니다.' and recv_check==0): prompt() except KeyboardInterrupt: clientSocket.close() sys.exit() | cs |
'Study > Python' 카테고리의 다른 글
코드 인젝션 활용 (0) | 2017.07.09 |
---|---|
윈도우 DEP 우회 (0) | 2017.07.03 |
PyDbg 접근 위반 핸들 (0) | 2017.07.03 |
윈도우 디버거 구현 (0) | 2017.07.03 |
ctypes 파이썬 외부 함수 라이브러리 (0) | 2017.06.13 |
Comments